Visual Studio でメモリリークの検出

今日は,Visual Studio 上で,C++コードのメモリリークの調査に明け暮れていた.CやC++のメモリリークは実に厄介.アプリケーションが終了するまで検出されないのだから,原因がどこにあるのか特定するのは困難を極める.

しかし,長年の蓄積の結果,その苦労を軽減してくれるツールが揃っている.今回は,Visual Studio に備わっている機能を使ってみた.基本的な仕組みを説明すると,メモリ確保のmalloc や new と,解放する free や delete を,リーク検出の機能をほどこしたもので置き換えてしまう,というもの.

具体的な方法については,マイクロソフトのサイトが詳しい.簡単に書いておくと,まず,リークを検出したいソース(.cpp)ファイルの先頭に,次の3行を追加する.
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
そして,最初に実行される関数本体の中に,次のステートメントを追加すればおしまい.
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

ビルドしてデバッグ実行をすると,メモリリークが検出されたときに,デバッグメッセージに表示される.

試してみたい人は,次のようなコードを書いてみるといいだろう.
#include "stdafx.h"

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

int _tmain(int argc, _TCHAR* argv[])
{
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    int *p = new int; // this memory will leak
    return 0;
}
これをデバッグ実行すると,次のようなメモリリーク検出メッセージが表示される.MFCを使っていると,ファイル名と行番号まで特定されるのだが...Visual C++ 2008 Express Edition を使っているから御愛嬌ということで...
Detected memory leaks!
Dumping objects ->
{100} normal block at 0x00377550, 4 bytes long.
 Data: <    > CD CD CD CD 
Object dump complete.

CodeGuruへの投稿にもいろいろ詳しい説明を見つけた.

上の投稿にも書かれているが,ファイル名を行番号を表示する方法がわかったので,追記しておく.メモリ確保の new が使われる前に,次のように#defineしてやればよい.
#include "stdafx.h"
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define new ::new(_NORMAL_BLOCK, __FILE__, __LINE__)

int _tmain(int argc, _TCHAR* argv[])
{
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    int *p = new int; // this memory will leak
    return 0;
}

これを上の例に適用してやると,出力はこんな感じになる.
Detected memory leaks!
Dumping objects ->
c:\users\tetsuo\documents\visual studio 2008\projects\testconsoleapp\testconsoleapp\testconsoleapp.cpp(10) : {100} normal block at 0x00547550, 4 bytes long.
 Data: <    > CD CD CD CD 
Object dump complete.

コメント

このブログの人気の投稿

Gbps でなく GT/s

HCSLに33オームの直列抵抗が必要な理由

PowerShellによるExcel/PowerPointの操作