_CRTDBG_MAP_ALLOC宏无法按预期工作

本文可帮助你解决当操作员分配对象并由 C 运行时库中调试例程转储时,Crtdbg.h 文件中的分配new报告为发生的问题。

原始产品版本: Visual C++
原始 KB 数: 140858

现象

当对象通过使用new运算符进行分配并通过使用 C 运行时库中的调试例程转储时,将报告在 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调用,但它不会存储正确的源文件或行号信息。 有两种方法可以标记正确的文件名和行号:

  • 直接调用运算符的 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 );
}