こんにちは。いつもお世話になっております。
メモリリーク検出について教えて頂けますか。
環境は、
・Windows XP Professional
・Microsoft C++ .NET
の組み合わせです。
以下は、「Win32 プロジェクト」ウィザードで作成したものをベースに少しロジックを追
加したものです。MFCは使用しません。
------------------------------------------------------------------------------
// LeakTest.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
#include stdafx.h
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
int _tmain(int argc, _TCHAR* argv[])
{
char* pText = new char [10];
for(int i = 0; i < 5; i++)
{
pText[i] = 'a' + i;
}
//delete [] pText;
_CrtDumpMemoryLeaks();
return 0;
}
------------------------------------------------------------------------------
これを実際に実行すると、出力ウィンドウには以下のように出力されます。
------------------------------------------------------------------------------
Detected memory leaks!
Dumping objects ->
d:\program files\microsoft visual studio .net\vc7\include\crtdbg.h(677) : {56}
normal block at 0x00373C18, 10 bytes long.
Data: <abcde > 61 62 63 64 65 CD CD CD CD CD
Object dump complete.
プログラム '[3784] LeakTest.exe: ネイティブ' はコード 0 (0x0) で終了しました。
------------------------------------------------------------------------------
問題は、
------------------------------------------------------------------------------
d:\program files\microsoft visual studio .net\vc7\include\crtdbg.h(677) : {56}
normal block at 0x00373C18, 10 bytes long.
------------------------------------------------------------------------------
の部分です。私は最初、ここの部分にはてっきりnewを行なった行が出力されるものと思
っていたのですが、実際にはCRT Libraryのヘッダの行数が出力されてしまっています。
MSDNの「メモリ リーク検出の有効化」をみると、
------------------------------------------------------------------------------
_CRTDBG_MAP_ALLOC が定義されている場合は、リークしたメモリが割り当てられたファイ
ルの名前も表示されます。ファイル名に続くかっこ内の数字 (この例では 20) は、ファ
イル内の行番号です。
------------------------------------------------------------------------------
と記述されています。
私は、この記述のとおり、リークしていると思われるメモリを割り当てたソースと行数を
知りたいのですが(つまり、この例だとLeakTest.cpp(12)のような)、何か記述の仕方に問
題があるのでしょうか?
#MFCは使用しないという条件があります。
よろしくお願い致します。
MSDNによると「_CRTDBG_MAP_ALLOC」は…
> このフラグは CRTDBG.H 中で宣言されています。
…とあるので、少なくとも…
> #define _CRTDBG_MAP_ALLOC
> #include <stdlib.h>
> #include <crtdbg.h>
…ではなく
#include <stdlib.h>
#include <crtdbg.h>
#define _CRTDBG_MAP_ALLOC
…としないと駄目なようですね。上記のように設定すると、一部メッセージが
改善されるようですが、依然としてshimodateさんが希望される動作は実現
できないようなので、残りの部分をご存じの方は是非よろしくお願いします。(^^;
あっ、定義位置は関係なかったみたい。(^^;;;
ごめんなさい。
こんな感じかと思います
#include stdafx.h
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#if defined(_DEBUG)
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
int main(int argc, char* argv[])
{
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
char* p = new char[100];
return 0;
}
_CrtDumpMemoryLeaks();は使ったことがないので知らないです
>#define _CRTDBG_MAP_ALLOC
の CRT は C の RunTime という意味合いですから C のランタイムのメモリー
確保周りにデバッグ用の仕掛けを仕込みますという事を示すのですね
new は C++ の部分ですから C の RunTime では new に関することは直接は
判りません。ただ、普通の実装なら new は malloc か calloc かを用いる
でしょうから(そうでないと _CRTDBG_MAP_ALLOC が定義してあっても捕捉出来ない)
、その意味で捕捉可能なのでしょう
> の CRT は C の RunTime という意味合いですから C のランタイムのメモリー
> 確保周りにデバッグ用の仕掛けを仕込みますという事を示すのですね
あっ、なるほど、確かに…
> char* pText = new char [10];
…を…
char* pText = (char *)malloc( 10 );
…に変更すると、正しくソースと行番号が表示されますね。(^^)
ありがとうございました。
解決しました。
どのように解決なさったのか誰にでも判るように書いてくれませんか?
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
をソースの先頭に記述することで解決しました。
kuさん、ありがとうございました。