メモリリークの場所をダンプする方法について – プログラミング – Home

メモリリークの場所をダンプする方法につ...
 
通知
すべてクリア

[解決済] メモリリークの場所をダンプする方法について


shimodate
 shimodate
(@shimodate)
ゲスト
結合: 22年前
投稿: 17
Topic starter  

こんにちは。いつもお世話になっております。
メモリリーク検出について教えて頂けますか。

環境は、
・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は使用しないという条件があります。

よろしくお願い致します。


引用未解決
トピックタグ
直感野郎Aチーム
 直感野郎Aチーム
(@直感野郎Aチーム)
ゲスト
結合: 22年前
投稿: 14
 

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さんが希望される動作は実現
できないようなので、残りの部分をご存じの方は是非よろしくお願いします。(^^;


返信引用
直感野郎Aチーム
 直感野郎Aチーム
(@直感野郎Aチーム)
ゲスト
結合: 22年前
投稿: 14
 

あっ、定義位置は関係なかったみたい。(^^;;;
ごめんなさい。


返信引用
ku
 ku
(@ku)
ゲスト
結合: 25年前
投稿: 312
 

こんな感じかと思います

#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();は使ったことがないので知らないです


返信引用
島
 島
(@島)
ゲスト
結合: 23年前
投稿: 238
 

>#define _CRTDBG_MAP_ALLOC

の CRT は C の RunTime という意味合いですから C のランタイムのメモリー
確保周りにデバッグ用の仕掛けを仕込みますという事を示すのですね

new は C++ の部分ですから C の RunTime では new に関することは直接は
判りません。ただ、普通の実装なら new は malloc か calloc かを用いる
でしょうから(そうでないと _CRTDBG_MAP_ALLOC が定義してあっても捕捉出来ない)
、その意味で捕捉可能なのでしょう


返信引用
直感野郎Aチーム
 直感野郎Aチーム
(@直感野郎Aチーム)
ゲスト
結合: 22年前
投稿: 14
 

> の CRT は C の RunTime という意味合いですから C のランタイムのメモリー
> 確保周りにデバッグ用の仕掛けを仕込みますという事を示すのですね

あっ、なるほど、確かに…

> char* pText = new char [10];

…を…

char* pText = (char *)malloc( 10 );

…に変更すると、正しくソースと行番号が表示されますね。(^^)


返信引用
shimodate
 shimodate
(@shimodate)
ゲスト
結合: 22年前
投稿: 17
Topic starter  

ありがとうございました。
解決しました。


返信引用
島
 島
(@島)
ゲスト
結合: 23年前
投稿: 238
 

どのように解決なさったのか誰にでも判るように書いてくれませんか?


返信引用
shimodate
 shimodate
(@shimodate)
ゲスト
結合: 22年前
投稿: 17
Topic starter  

#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
をソースの先頭に記述することで解決しました。
kuさん、ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました