16

我正在使用 Visual Studio 2010 中的 SDL 开发游戏。我遇到了_CrtDumpMemoryLeaks()宏,并认为我会试一试。调用_CrtDumpMemoryLeaks()确实将内存泄漏打印到输出窗口,但它没有显示它发生的位置。

我已经阅读了Memory Leak Detection Enabling上的 MSDN 文章,它解释说,如果我定义_CRTDBG_MAP_ALLOC它应该输出违规语句的行号。这在我的情况下不会发生。(但是,如果我直接使用 malloc() 而不是使用'new',我就可以让它工作)。

编码:

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int *var = new int(5);

    _CrtDumpMemoryLeaks();

    return 0;
}

输出如下:

Detected memory leaks!
Dumping objects ->
{58} normal block at 0x007D1510, 4 bytes long.
 Data: <    > 05 00 00 00 
Object dump complete.

如果_CrtDumpMemoryLeaks()在使用“新”进行分配时无法输出行号,那么我们将不胜感激提出其他实现类似行为的方法的建议。

4

5 回答 5

9

那是 Visual Leak Detector 的旧版本。

试试这个:http: //vld.codeplex.com/

于 2010-07-08T10:40:49.333 回答
9

当您定义 _DEBUG 并包含时,<crtdbg.h>您会得到一个重载operator new,它采用附加参数,您可以使用这些参数在放置new表达式中指定文件和行号。

例如

int* p = new (_NORMAL_BLOCK, __FILE__, __LINE__) int(5);

您可以将其包装在有条件定义的宏中,例如

#ifdef _DEBUG
#define DEBUG_NEW_PLACEMENT (_NORMAL_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_NEW_PLACEMENT
#endif

int* p = new DEBUG_NEW_PLACEMENT int(5);

虽然您确实看到人们定义了一个宏new来完全隐藏此表单客户端代码,但我个人并不推荐它,因为它会破坏任何已经故意使用 Placement new 的内容,并且您必须确保任何使用 Placement new 的标头(例如许多标准标头)包含在任何标题重新定义之前new。这可以很容易地让new头文件中的一些内联使用不被“调整”。

于 2010-07-08T12:18:09.637 回答
3

包含后您可能需要这些定义


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
于 2010-07-08T10:15:28.697 回答
2

查看这段代码。

重载 operator new 和 operator delete 以记录所有内存分配和释放

我使用这种方法确定了我的内存泄漏。

于 2010-07-08T12:06:49.803 回答
2

Charles Bailey 接受的答案要求您更改源代码,这不是必需的。如果您使用newand delete(或数组版本),您需要做的就是将此代码片段放在stdafx.h每个项目的文件中(包括任何静态或动态库依赖项),然后它将给出一个源文件和行附加到每个泄漏的内存对象的编号:

#ifdef _DEBUG
   #ifndef DBG_NEW
      #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
      #define new DBG_NEW
   #endif
#endif  // _DEBUG

这直接来自微软关于此事的网页。

于 2016-01-01T23:26:06.840 回答