_CrtDumpMemoryLeaks无输出的主因是未启用调试堆追踪或配置错误:_CRTDBG_MAP_ALLOC宏须在#include 和前定义,且需调用_CrtSetDbgFlag设置标志;项目须为Debug配置,避免异常退出,并重载operator new/delete以捕获new/delete泄漏;定位靠分配序号断点或_MAP_ALLOC行号;但CRT不检测STL内部裸指针、句柄等非CRT堆资源。

它能检测 malloc/calloc/realloc 分配的泄漏,但默认不抓 new/delete;必须在 Debug 配置下启用,且头文件顺序和宏定义缺一不可。
为什么 _CrtDumpMemoryLeaks 没输出?
最常见原因是没开调试堆追踪或配置不对:
-
_CRTDBG_MAP_ALLOC宏必须在#include <stdlib.h></stdlib.h>和#include <crtdbg.h></crtdbg.h>之前定义,顺序错会导致映射失效 - 只调用
_CrtDumpMemoryLeaks()但漏了_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF),结果程序退出时不自动检查 - 项目不是
Debug配置(Release 下_DEBUG未定义,crtdbg.h中的调试函数直接跳过) - 程序异常崩溃或
exit()退出,_CrtDumpMemoryLeaks没机会执行
如何让 new/delete 也被报告?
CRT 默认只拦截 malloc 系列,new 走的是 operator new 实现。要覆盖它,得手动重载:
- 在所有使用
new的源文件都可见的头中(比如debug_new.h),加如下代码:
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
void* operator new(size_t size) {
return _malloc_dbg(size, _NORMAL_BLOCK, __FILE__, __LINE__);
}
void operator delete(void* ptr) noexcept {
_free_dbg(ptr, _NORMAL_BLOCK);
}
#endif- 确保该头在
#include <iostream></iostream>等标准头之前引入,否则某些模板实例化可能提前绑定默认operator new - 不要在 Release 构建中保留这段代码,否则链接会报重复定义错误
怎么定位泄漏发生在哪一行?
泄漏报告里带编号(如 {453})的那一行,就是关键线索:
立即学习“C++免费学习笔记(深入)”;
- 在
main()开头加_CrtSetBreakAlloc(453);,运行时会在第 453 次分配处断点,直接停在new或malloc调用行 - 如果用了
_CRTDBG_MAP_ALLOC,报告里会显示类似leaktest.cpp(20),双击这行或按F4就跳转到源码 - 注意:多线程环境下,分配序号不严格对应源码顺序,建议临时禁用并发路径再测
真正容易被忽略的是:CRT 不管 STL 容器内部资源(比如 std::vector 里存的裸指针没 delete),也不管 Windows 句柄、GDI 对象这类非堆内存——它只盯着 CRT 堆上的 malloc 和你重载后的 new。别指望靠它发现所有“泄漏”。


















