動的配列の範囲外アクセス(書き込み)、メモリリーク、二重解放はMicrosoftのcrtdbgで動的検出できます。
ただし、動的配列の範囲外アクセス(読み込み)はcrtdbgでは検出できません。
これを検出可能にする機構 RobustArrayNewを作成しました。
ヘッダを1つインクルードし、デバッグビルドするだけで、動的検出が可能です。
ここでは、RobustArrayNewの仕組みと使い方を紹介します。
Windowsはページ単位でメモリの属性を変更出来るため、operator new[]を上書きし
[詰め物領域] + [サイズ領域] + [実領域] + [ガード領域]という構成のメモリを確保します。
その際、[詰め物領域] + [サイズ領域] + [実領域]を、ページサイズ境界に合わせておきます。
その後、[ガード領域]を読み取り/書き込み不可にします。
こうすることで、[実領域]を1バイトでも超えてアクセスすると、確実に例外が発生するようになります。
RobustArrayNewとcrtdbgは相互補完の関係にあります。
しかし、この2つを同時に使用することはできません。
なので、以下の様なマクロを使い、どちらか一方が有効になるようにすることをおすすめします。
RobustArrayNewの中に、以下のマクロを含むサンプルも収録してあります。
1 2 3 4 5 6 7 8 9 10 11
- | !// エントリポイント(main, _tmain, WinMain, dllmain, etc...)のあるソースに以下のマクロを定義します // プロジェクト内に#define new DEBUG_NEWがある場合は、削除してください #ifdef _DEBUG #ifdef ENABLED_ROBUST_ARRAY_NEW #include "RobustArrayNew.h" #else #define _CRTDBG_MAP_ALLOC #include <crtdbg.h> #define new ::new(_NORMAL_BLOCK, __FILE__, __LINE__) #endif // ENABLED_ROBUST_ARRAY_NEW #endif // _DEBUG
1 2 3 4 5 6 7 8 9 10 11 12
- !// エントリポイント(main, _tmain, WinMain, dllmain, etc...)先頭付近に以下のマクロを定義します #ifdef _DEBUG #ifndef ENABLED_ROBUST_ARRAY_NEW _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); _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif // ENABLED_ROBUST_ARRAY_NEW #endif // _DEBUG