_CRTDBG_MAP_ALLOC マクロが期待どおりに機能しない

この記事では、オブジェクトが演算子によって割り当てられ、C Run-Time ライブラリのデバッグ ルーチンによってnewダンプされるときに、Crtdbg.h ファイルで割り当てが発生していると報告される問題を解決するのに役立ちます。

元の製品バージョン: Visual C++
元の KB 番号: 140858

現象

オブジェクトが演算子を new 使用して割り当てられ、C Run-Time ライブラリのデバッグ ルーチンを使用してダンプされると、割り当ては Crtdbg.h ファイル行 512 で発生したと報告されます。

原因

これは、Crtdbg.h ファイルのオーバーロードされた演算子newの定義によって発生します。

#ifdef _CRTDBG_MAP_ALLOC
inline void* __cdecl operator new(unsigned int s)
    { return ::operator new(s, _NORMAL_BLOCK, __FILE__, __LINE__); }
#endif /* _CRTDBG_MAP_ALLOC */

現在のファイル名と__LINE__行番号を報告するコンパイラによって定義されたマクロを次__FILE__に示します。 マクロはプリプロセッサによって入力されます。 次に、コンパイラは の呼び出しをこの関数に new 置き換えます。 したがって、マクロはインライン化される前に既に入力されています。 そのため、ヘッダー ファイル情報が報告されます。

解決方法

シンボルを _CRTDBG_MAP_ALLOC 定義すると、コード内のすべての インスタンス new がのデバッグ バージョンに適切にマップされ、ソース ファイルと行番号の new 情報が記録されます。

これはのデバッグ バージョン newへの呼び出しをマップすることは事実ですが、適切なソース ファイルや行番号情報は格納されません。 正しいファイル名と行番号をマークするには、次の 2 つの方法があります。

  • 演算子のデバッグ バージョンを new 直接呼び出します。
  • 次のサンプル コードのように、デバッグ モードで演算子 new を置き換えるマクロを作成します。

サンプル コード

/* MyDbgNew.h
/* Defines global operator new to allocate from
/* client blocks*/
#ifdef _DEBUG
    #define MYDEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__)
    // Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the
    //allocations to be of _CLIENT_BLOCK type
#else
    #define MYDEBUG_NEW
#endif // _DEBUG
/* MyApp.cpp
/* Compile options needed: /Zi /D_DEBUG /MLd
/* or use a
/* Default Workspace for a Console Application to
/* build a Debug version*/
#include "crtdbg.h"
#include "mydbgnew.h"

#ifdef _DEBUG
    #define new MYDEBUG_NEW
#endif

void main( )
{
    char *p1;
    p1 = new char[40];
    _CrtMemDumpAllObjectsSince( NULL );
}