スポンサーリンク

VC++でcrtdbg.hでメモリリークを検出

#include <iostream>

// メモリリークを検出した位置を表示するためのマクロ
#define _CRTDBG_MAP_ALLOC

// メモリリークの検出
#include <crtdbg.h>

// メモリリークしたメモリのnewした場所のファイル名と行数を表示する
// #define _CRTDBG_MAP_ALLOC で動く機能のはずなのだがなぜか機能しないので自分で定義する
#define new ::new(_NORMAL_BLOCK, __FILE__, __LINE__)


class Dummy
{
public:

	char* myleak() {
        char* p = new char[3] {0, 0, 0}; // メモリリークしている (19行目)
        return p;
	}

	void mysafety() {
        int* q = new int[3] {1, 1, 1}; // メモリリークしていない (24行目)
        printf("%d %d %d\n", q[0], q[1], q[2]);
        delete [] q;
	}

    Dummy() {}
    ~Dummy() {}
};

int main()
{
    // アプリケーション終了時に_CrtDumpMemoryLeaks()が呼ばれるように指示
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    
    Dummy d;
    std::cout << "Hello World!\n";
    char* c = d.myleak();
    d.mysafety();
    
    // 出力内容と出力先
    // https://learn.microsoft.com/ja-jp/cpp/c-runtime-library/reference/crtsetreportmode?view=msvc-170
    // _CRT_WARN          ... 警告、メッセージ、およびすぐに注意する必要のない情報。
    // _CRTDBG_MODE_DEBUG ... デバッガーの出力ウィンドウにメッセージを書き込みます。
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
    
    // メモリリークの情報を出力
    // この関数は、呼び出された時点で解放されていないメモリを全て検知する。
    // アプリケーション終了時でのリークを検出したいならここで書かないで
    // _CrtSetDbgFlagでプログラムが終了したときに自動的に呼び出されるように指示したほうがいい。
    // _CrtDumpMemoryLeaks();
    
    return 0;
}

出力

_CrtSetReportMode関数で_CRTDBG_MODE_DEBUGを指定しているので、デバッグウィンドウに以下の出力がされる。

ファイル名 , newした行番号 , newしたメモリサイズ がそれぞれ出力される。

Detected memory leaks!
Dumping objects ->
C:\myproj\ConsoleApplication5\ConsoleApplication5.cpp(19) : {161} normal block at 0x0000029DA8896EA0, 3 bytes long.
 Data: <   > 00 00 00
Object dump complete.
プログラム '[26332] ConsoleApplication5.exe' はコード 0 (0x0) で終了しました。

参考

癖をまとめてくれているサイト。

プログラマの友

http://www7b.biglobe.ne.jp/~robe/pf/pf008.html

このcrtdbg.hによるメモリリーク検出、プロジェクトの規模が大きくなってくるとかなり気を遣わなければいけないらしい。

閑古鳥

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: