我正在使用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()
在使用'new'进行分配时无法输出行号,则可以了解其他实现类似行为的方法。
答案 0 :(得分:9)
当你定义_DEBUG并包含<crtdbg.h>
时,你会得到一个重载的operator new
,它会带来额外的参数,你可以用这些参数来指定展示位置new
表达式中的文件和行号。
E.g。
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
以完全隐藏此表单客户端代码,但我个人并不推荐它,因为它会破坏任何已经故意使用新版本的内容,并且您必须确保使用展示位置的任何标头在任何标题重新定义new
之前包含新的(例如许多标准标题)。这样可以很容易地让标题文件中的new
内联使用不会被“调整”。
答案 1 :(得分:8)
这是Visual Leak Detector的旧版本。
答案 2 :(得分:3)
您的包含
后可能需要这些定义
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
答案 3 :(得分:2)
查看这段代码。
Overloading operator new and operator delete to log all memory allocations and deallocations
我使用这种方法确定了我的内存泄漏。
答案 4 :(得分:2)
Charles Bailey接受的答案要求您更改源代码,这不是必需的。如果您使用的是new
和delete
(或数组版本),您只需将此代码段放在每个项目的stdafx.h
文件中(包括任何静态或动态库依赖项),然后它将为每个泄漏的内存对象提供一个源文件和行号:
#ifdef _DEBUG
#ifndef DBG_NEW
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
#define new DBG_NEW
#endif
#endif // _DEBUG
这直接来自微软webpage就此事。