Last-modified: 2014-11-02 (日) 14:11:02
C++/メモリリークを検出したい


概要

Windowsであれば、Microsoftのcrtdbg機能が使えます。
MFCを使っている場合は、デフォルトでDebugビルド時に一部のメモリリークを検出できます。
しかし、検出できる項目が足りないですし、デバッガーの出力ウィンドウにしか表示されないので物足りません。
以下の様なコードをプロジェクト毎に埋め込むと、メモリリーク検出処理がカスタマイズできます。
ただし、crtdbgでは動的配列外アクセス(読み込み)は検出出来ないので、RobustArrayNewと組み合わせるとより効果的です。
crtdbgの動作サンプルも、RobustArrayNewにあります。

ソース

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
-
|
!
 
 
 
 
 
 
 
-
-
!
|
|
|
|
|
|
-
|
|
|
|
|
|
!
|
|
|
-
|
!
// エントリポイント(main, _tmain, WinMain, dllmain, etc...)のあるソースに以下のマクロを定義します
// プロジェクト内に#define new DEBUG_NEWがある場合は、削除してください
#ifdef _DEBUG
    #define _CRTDBG_MAP_ALLOC
    #include <crtdbg.h>
    #define new ::new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif    // _DEBUG
 
 
int _tmain(int /*argc*/, _TCHAR* /*argv[]*/)
{
// エントリポイント(main, _tmain, WinMain, dllmain, etc...)先頭付近に以下のマクロを定義します
#ifdef _DEBUG
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
    // _CRTDBG_CHECK_ALWAYS_DFを指定すると、メモリ確保/解放の度に_CrtCheckMemoryを呼ぶため、壊滅的に遅くなります
    //  これで得られる恩恵はまずありません
    //  どうしても使いたい場合は、(_CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_CHECK_EVERY_128_DF)などとして、呼び出しタイミングを制御します
    // _CRTDBG_DELAY_FREE_MEM_DFを指定すると、解放してもヒープリストから削除しなくなるためメモリ不足をエミュレートできます
    //  これで得られる恩恵もまずありません
    // _CRTDBG_CHECK_CRT_DFを指定すると、CRT内部で使用しているメモリに関して報告を上げるため、ノイズだらけになります
    //   これを指定する機会はありません
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif    // _DEBUG
    
 
    // 処理
    // ・・・
]

検証時の環境