- 追加された行はこの色です。
- 削除された行はこの色です。
メモリリークは
メモリリークは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);
メモリリークを検出するにはデバック開始を選択しプログラムを起動します
&ref(debug.png);
すると、プログラム終了時に出力の欄に次のように出るはずです
Detected Memory leaks!
以下がメモリリークを発生しているメモリを表わしています
&ref(isleak.png);
{58}となっているのがメモリリークを起こしているメモリ番号です
人によって違う番号が出てるかも知れません
プログラム上のメモリリークの発生している箇所を探すには次のコメントアウトをはずします
// CRTメモリリーク箇所検出
_CrtSetBreakAlloc(58);
ここでは58としていますが、先ほどのメモリリークが発生しているメモリ番号を指定してください
再度デバック起動をすると、プログラムが途中で止まります
&ref(leak.png);
この時、呼び出し履歴の欄を見てください
呼び出し履歴には関数がどの順番で呼び出されたのかの履歴が残っています
上から4行はmalloc関数の内部での呼び出し行を示しているので直接の原因ではありません
直接の原因となっているのはmalloc関数をプログラム上で呼び出した行なので
赤枠の行をダブルクリックします
すると、メモリリークの原因となっているmalloc関数を呼び出している行に飛びます
&ref(error.png);
緑の矢印が原因となっている行を指します
これでメモリリークを起こしているプログラム行の特定ができました
ここでは単純なプログラムでしたが
ソースコードが複数ファイルある場合でも検出と箇所の特定が可能です
巨大なプログラムになるほどデバックは大変になりますが
この方法でメモリリークの除去は可能となるので是非有効活用してください
ちなみに、このコードでC++のnewによるメモリリークも同様に検出できます