メモリリークを検出したい – プログラミング – Home

メモリリークを検出したい
 
通知
すべてクリア

メモリリークを検出したい


フィナーレ
 フィナーレ
(@フィナーレ)
ゲスト
結合: 22年前
投稿: 2
Topic starter  

newとdeleteをオーバーロードして、newが使用された情報を保存したいのです。
newを「new(__FILE__,__LINE__)」として呼び出しことで実現しています。

しかし引数付きdeleteの呼び出し方が解りません
delete(__FILE__,__LINE__)とすると

C2541: delete : 'delete' 演算子が、ポインタでないオブジェクトに用いられています。

というエラーが出てしまいます。
どうすれは引数付きdeleteを呼び出せるのでしょうか。

開発環境は VC++6.0 Professional Windows2000 MFCは使いません

どうかご教授願います。


引用解決済
トピックタグ
くたくた
 くたくた
(@くたくた)
ゲスト
結合: 23年前
投稿: 119
 

http://www.microsoft.com/japan/developer/library/dsmsdn/deep100799.htm
の「手作業による operator delete の呼び出し」という項目が解決策になると思います。


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

deleteをオーバーロードしなくても、私のほうではうまく行ってますよ。
オーバーロードしているのはnewとmalloc()関連関数だけです。


返信引用
なおや
 なおや
(@なおや)
ゲスト
結合: 24年前
投稿: 3
 

質問内容とは違うかもしれないですが、タイトルには「メモリリーク検出」と
あるのでカキコします。

自分では下記の内容をヘッダに入れて、調査しています。

#include <crtdbg.h>
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#define malloc(p1) _malloc_dbg(p1,_NORMAL_BLOCK,__FILE__,__LINE__)
#define LeakCheck() { \
int iDbgFlg; \
iDbgFlg = _CrtSetDbgFlag(0); \
_CrtSetDbgFlag( iDbgFlg | _CRTDBG_LEAK_CHECK_DF); \
}
#else
#define LeakCheck() (void)0

使い方は
プログラムのはじめに一度「LeakCheck();」を書きます。そして、デバッグ実行
して、終了した時に出力ウィンドウに表記されなければリークなし、表記されれば
リークありとしています。
ただ困るのが実行されないと(コードが走らないと)、意味がないことです。
使ってみてはどうでしょうか?


返信引用
フィナーレ
 フィナーレ
(@フィナーレ)
ゲスト
結合: 22年前
投稿: 2
Topic starter  

なおやさんに質問なんですが
new(_NORMAL_BLOCK,__FILE__,__LINE__)
とはなんなんでしょう。
operator newのデバッグバージョンなんだろーな、と思いますけど。


返信引用
なおや
 なおや
(@なおや)
ゲスト
結合: 24年前
投稿: 3
 

# new(_NORMAL_BLOCK,__FILE__,__LINE__)
# とはなんなんでしょう。
質問されても、自分は他のサイトの掲示板(過去ログ)を見て使用し始めたため、
内容に関しては・・・。
MSDNを参考にして下さい。
http://www.microsoft.com/japan/msdn/library/default.asp?
url=/japan/msdn/library/ja/vsdebug/html/_core_using_the_debug_heap_from_c2b2b.a
sp

すみません。今見たら二行抜けていました。
#ifdef _DEBUG ←抜けていた行
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#define malloc(p1) _malloc_dbg(p1,_NORMAL_BLOCK,__FILE__,__LINE__)
#define LeakCheck() { \
int iDbgFlg; \
iDbgFlg = _CrtSetDbgFlag(0); \
_CrtSetDbgFlag( iDbgFlg | _CRTDBG_LEAK_CHECK_DF); \
}
#else
#define LeakCheck() (void)0
#endif // _DEBUG ←抜けていた行


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 22年前
投稿: 320
 

> newとdeleteをオーバーロードして、newが使用された情報を保存したいのです。
> newを「new(__FILE__,__LINE__)」として呼び出しことで実現しています。
> しかし引数付きdeleteの呼び出し方が解りません
> delete(__FILE__,__LINE__)とすると
> C2541: delete : 'delete' 演算子が、ポインタでないオブジェ
クトに用いられています。
> というエラーが出てしまいます。
> どうすれは引数付きdeleteを呼び出せるのでしょうか。

Deep C++に説明はあると思いますが,書いておきますと……。

多重定義されたoperator deleteは,通常は呼び出されません。
多重定義されたoperator deleteが使われるのは,
newで生成されたオブジェクトのコンストラクタが例外を発生して,オブジェ
クトが生成されなかったときです。

この場合,newによって呼び出されたoperator newと対応するoperator
deleteが呼び出されます。
対応する,というのは,
void * operator new (std::size_t, T1, T2, ...);
に対して,
void operator delete (void *, T1, T2, ...);
または
void operator delete (void *, std::size_t, T1, T2, ...);
のことです。

例外がなく,オブジェクトの破棄にdeleteを使った場合,
void operator delete (void *);
があればそれを,なければ
void operator delete (void *, std::size_t);
を使います。

結局のところ,delete演算子では追加引数のついたoperator deleteは呼び出せない,
ということになります。

呼び出すためには,
T * obj = new(__FILE__, __LINE__) T;
としたなら,
obj->~T();
operator delete(obj, __FILE__, __LINE);
と明示的にデストラクタとoperator deleteを呼ぶ必要があります。

> new(_NORMAL_BLOCK,__FILE__,__LINE__)
> とはなんなんでしょう。
> operator newのデバッグバージョンなんだろーな、と思いますけど。

VC++のCRTに入っている,デバッグ用のoperator newを呼び出すための構文です。
crtdbg.hで定義されています。

ブロックに,__FILE__と__LINE__が記録されます。
そして,_CrtDumpMemoryLeaksによってリークが出力されたときに,
newを呼び出した時の__FILE__と__LINE__が出力の中に含まれるようになります。
http://www.microsoft.
com/japan/msdn/vs_previous/visualc/techmat/feature/MemLeaks/default.htm

> #define new new(_NORMAL_BLOCK,__FILE__,__LINE__)

これは危険ですよ……。
標準C++のヘッダファイルを読み込んだときに,大量のエラーをだすもととなります。
#if defined(_DEBUG)
#define New new(_NORMAL_BLOCK, __FILE__, __LINE__)
#else
#define New new
#endif
として,newではなくNewを使うようにするとよいです。

> #define malloc(p1) _malloc_dbg(p1,_NORMAL_BLOCK,__FILE__,__LINE__)

これだと,mallocとfreeの対応がとれないですが……。

_CRTDBG_MAP_ALLOCをcrtdbg.hを読み込む前に定義しておけば,
malloc, freeなどを全てデバッグ版にマップしてくれます。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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