輝々凛々

ガンバるってことは、素晴らしい事だ。

メモリリークチェケラッチョ

今日の議題は「メモリリーク」。


まずメモリっていうのは、簡単にいえば作業域。
お好み焼きを作る鉄板みたいなものです。

やっぱ作業領域ってのは大きい方が効率よく仕事ができるので
パソコンのスペックで、メモリの容量ってのは結構重要なのです。
(お好み焼きに限って言えば広すぎても作業しにくいけど)


んで、ここまでは物理的な話。

次。
作業する場所はきれいにしておかないと作業効率悪いよね?(どき?)
そして無駄なものは、さっさと作業台から撤去するに限るよね?

そんなわけでメモリリークのお話。
まず「メモリを確保する」っていう言葉がプログラミングにはあります。
この「メモリを確保する」っていう言葉の意味は、
「これから作業をする上でのメモリの間借り」的な意味があります。
(何も物理的にメモリが増えるわけじゃないです)

メモリ確保の手段は、Cならmalloc、C++ならnewを使います。
(他にもあるんだけど割愛・・
 やっぱ補足しておくと、int hoge;と宣言するだけでもメモリ確保なんだけど
 これはどっちかっていうと「あらかじめ用意されてたものを使った」感じ)


んで、このmallocやnewで確保(獲得)したメモリ領域は、必ず解放する必要があります。
Cならfreeで、C++ならdeleteです。
(正確に言えば、プログラムが終了した後に、OSさんが作業領域を掃除してくれるのですけど・・
 掃除・・・
 掃除はしてくれないか)


でも、人間だもの。忘れるよね。



確保したメモリが解放されずに残ってしまう状態をメモリリークって言います。
メモリリークは問題なんですけど、何が問題なのかっていうと、

たとえば同じ処理をぐるぐる回している最中にメモリリークしていたら、
解放されずに残ったゴミのせいでどんどん作業領域が狭くなってしまいます。
これでは、ほんとドンドンと作業しにくくなってしまいます。


結果的に、プログラムが重くなってしまい、
ほんとシマイにはプログラムが強制的に終了してしまいます。



で、このメモリリークは単に確保した領域を
しかるべき場所でしかるべき時に解放すればいいだけの話なんですが、
これがなかなか難しいです。


そこでプロファイラっていうツールを使ってもいいんですが、
たいてい有償ですから、個人向けとかには使えません。

そこで活躍するのが、printfデバッグ・・・!
もそうですけど、今日はVisual C++のとあるライブラリ。

使用方法は簡単。

#include <crtdbg.h>
#define _CRTDBG_MAP_ALLOC
#define new ::new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define malloc(X) _malloc_dbg(X,_NORMAL_BLOCK,__FILE__,__LINE__)



をmain関数のあるファイルの頭に書き足します(標準ライブラリをインクルードした後)。
で、main関数の先頭で、

_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);


を呼び出せば、ザッツオールフォートゥデイ!です(意味不明)。

一応、VC2003/2005で以下のソースを確認済みです。

#include <stdlib.h>
#include <crtdbg.h>
#define _CRTDBG_MAP_ALLOC
#define new ::new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define malloc(X) _malloc_dbg(X,_NORMAL_BLOCK,__FILE__,__LINE__)

int main(void)
{
  _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

  new int(0);

  malloc(1);

  return 0;
}





これで、プログラム中のどこで確保したメモリがリークしているのかがわかります。
あくまで「どこで確保した」です。
解放する箇所は自分で決める必要があります。
が、
基本は「要らないものはすぐに消す」の精神です(きっと)。
関連記事

ツッコミの投稿


(ツッコミ非公開の場合はチェック)