12

のポイントはstatic char THIS_FILE[] = __FILE__;何ですか?

はじめに:それは何をしますか?それはどこから来たのですか?

Microsoft の Windows 用ネイティブ クラス ライブラリである MFC には、DEBUG_NEWメモリ割り当てとそれらが発生した場所 (ユーザー コード内) を追跡するマクロがあります。

これが機能するために、VS ウィザードは次のコード ブロックをすべての cpp ファイルに入れます: (ヘッダー ファイルではありません)。

#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
#endif

そして、debug new マクロは次のように定義されます (in afx.h):

#define DEBUG_NEW new(THIS_FILE, __LINE__)

機械全体で、次のような意味のある漏れ検出出力が得られます。

Detected memory leaks!
Dumping objects ->
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {615} normal block at 0x04081CE0, 56 bytes long.
 Data: <¬9Í]            > AC 39 CD 5D 13 00 00 00 13 00 00 00 01 00 00 00 
c:\my\dev\path\myfile.cpp(237) : {614} normal block at 0x04087FC0, 4 bytes long.
 Data: <ð   > F0 1C 08 04 
Object dump complete.

それで、もう一度質問は何ですか?

私が困惑しているのは、THIS_FILEchar 配列の目的です。機械は意味がありません。彼らが次のように定義した場合DEBUG_NEW

#define DEBUG_NEW new(__FILE__, __LINE__)

ifdefすべてのファイルにそのブロックを含める代わりに、ヘッダーに配置するだけで完了できます。

それで、のポイントはTHIS_FILE何ですか?

(ちなみに、これはまさに MS の CRT が行うことでmallocあり_malloc_dbg、ヘッダーでデバッグ マクロが次のように定義されている場所crtdbg.hです。

#define   malloc(s)             _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)

)

DEBUG_NEW繰り返しますが、単純な方法が (より良い) 機能するのに、MFC マクロで複雑な方法が行われるのはなぜですか?


更新:ハ!私は最近、VS2005 ウィザードがの定義を生成された cpp ファイルに入れていないことに気付きました。THIS_FILE

それを調査すると、MS はしばらく前にafxtempl.h、次のように定義されているように、もう必要ないと判断したようです。

#undef THIS_FILE
#define THIS_FILE __FILE__

それでも、なぜそれが必要だったのかという疑問は変わらないと思います。(そして、当時のメモリ要件の答えはかなり有効だと思います。)


4

3 に答える 3

9

デバッグ アロケータは、ファイル名へのポインタをヒープ ブロックに格納します。割り当てられたすべてのブロックにもファイル名用のスペースを割り当てる必要があるのではなく、わずか 4 バイトです。

これにより、リークしたブロックが DLL によって割り当てられ、リーク レポートが生成されるまでにその DLL がアンロードされた場合、デバッグ情報が失われる可能性があることに注意してください。

文字配列のみがTHIS_FILE、翻訳単位で常に同じであることが保証されています。いいえ、それ__FILE__はリテラルです。また、2 つのリテラルのアドレスが同じであるとは限りません。たとえ値が同じであっても、__FILE__.

于 2012-11-07T20:07:00.670 に答える
0

私は、これがコンパイルされたexe内のメモリブロックを描写していると信じており、間違っている可能性があります。これは、dll/exe がロードされたアドレスを知っていれば、メモリ アドレスのチェーンをたどって問題のあるコードを見つけることができる例外を取得する場合に役立ちます。

于 2012-11-07T19:51:21.363 に答える
0

__FILE____LINE__すべての行で変更されますが、ファイル全体で同じです。そのため、ファイルに大量のデバッグ コードがある場合、定数を適切にマージしない古いコンパイラでは、文字列 "filename.ext" の不要なコピーが大量に作成されます。-fno-merge-constants などで違いを確認できる場合があります(申し訳ありませんが、それはgcc CFLAGであり、VSについてはわかりません)。ほとんどのコンパイラはデフォルトで定数をマージするようになり、その定義が不要になりました。

于 2012-11-29T08:59:55.347 に答える