メモリリークはC/C++環境下におて
malloc関数で確保されたメモリをfree関数で解放し忘れた場合に起こります
C++のnewも内部的にはmallocしているため同様にメモリリークが発生します
これのまずいところは、プログラムを終了しても使われたメモリが解放されないところです
つまり、メモリ解放を忘れたプログラムを起動するたびに
使えるメモリ領域が減っていき、システムの性能が低下したり、不安定になったりします。
最悪の場合、アプリが落ちたり、システムを再起動する必要があります。

メモリリークは特にメモリが限られている環境(例えば携帯電話など)では致命的なエラーです
また、原因が見つかりにくいエラーなので必ずメモリリークはなくしましょう

以下にVC++でメモリリークの検出とメモリリーク箇所を特定する方法を示します。

#include <crtdbg.h>
#include <stdio.h>
#include <stdlib.h>

int main(){

	// CRTメモリリーク検出用
	_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
	// CRTメモリリーク箇所検出
	//_CrtSetBreakAlloc(58);

	int* a = (int*)malloc(sizeof(int) * 4); 
	//free(a); // freeし忘れでメモリリーク発生

	return 0;
}

メモリリーク検出には次のヘッダーが必要です

#include <crtdbg.h>

プログラムの先頭に次のコードを挿入します

// CRTメモリリーク検出用
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);

メモリリークを検出するにはデバック開始を選択しプログラムを起動します

debug.png

すると、プログラム終了時に出力の欄に次のように出るはずです
Detected Memory leaks!
以下がメモリリークを発生しているメモリを表わしています

isleak.png

{58}となっているのがメモリリークを起こしているメモリ番号です
人によって違う番号が出てるかも知れません
プログラム上のメモリリークの発生している箇所を探すには次のコメントアウトをはずします

// CRTメモリリーク箇所検出
_CrtSetBreakAlloc(58);

ここでは58としていますが、先ほどのメモリリークが発生しているメモリ番号を指定してください
再度デバック起動をすると、プログラムが途中で止まります

leak.png

この時、呼び出し履歴の欄を見てください
呼び出し履歴には関数がどの順番で呼び出されたのかの履歴が残っています
上から4行はmalloc関数の内部での呼び出し行を示しているので直接の原因ではありません
直接の原因となっているのはmalloc関数をプログラム上で呼び出した行なので
赤枠の行をダブルクリックします
すると、メモリリークの原因となっているmalloc関数を呼び出している行に飛びます

error.png

緑の矢印が原因となっている行を指します
これでメモリリークを起こしているプログラム行の特定ができました
ここでは単純なプログラムでしたが
ソースコードが複数ファイルある場合でも検出と箇所の特定が可能です
巨大なプログラムになるほどデバックは大変になりますが
この方法でメモリリークの除去は可能となるので是非有効活用してください


添付ファイル: fileerror.png 862件 [詳細] filedebug.png 926件 [詳細] fileisleak.png 969件 [詳細] fileleak.png 944件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2014-03-01 (土) 22:28:05