必须调用_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF)并包含,且仅在_DEBUG下生效;{123}是分配序号而非源码行号,需配合_CrtSetBreakAlloc(123)定位。
Visual Studio 调试器中开启内存泄漏检测必须加 _CrtSetDbgFlag
默认情况下,VS 的 C 运行时(CRT)不会自动报告内存泄漏,哪怕你用了 new 没配 delete。关键动作是手动启用调试堆并设置报告级别——最常用的是在 main() 开头或 WinMain() 里调用:
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
注意两点:
• 必须包含 头文件,且仅在 _DEBUG 宏定义下生效;
• _CRTDBG_LEAK_CHECK_DF 表示程序退出时自动检查泄漏,不是实时监控;
• 如果只设了 _CRTDBG_ALLOC_MEM_DF 而没加泄漏检查标志,运行结束时不会输出任何泄漏信息。
泄漏报告里的 {123} 行号不是源码行号,而是分配序号
VS 输出的泄漏信息形如:
Detecting memory leaks...
Detected memory leaks!
Dumping objects ->
{18} normal block at 0x00B9A568, 4 bytes long.
Data: CD CD CD CD
这个 {18} 是 CRT 内部按分配顺序给的编号,不是你代码第 18 行。要定位源头,得配合 _CrtSetBreakAlloc(18) 在第 18 次分配时中断:
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetBreakAlloc(18); // 加在 main 开头,运行后会在该次 new/malloc 处中断
常见误区:
• 直接看泄漏报告里“file:line”字段——它只对用 _malloc_dbg 或重载了带文件/行号参数的 operator new 才有效;
• 忘记在 Debug 模式下编译:Release 模式下 _Crt*() 函数全为空操作;
• 在 DLL 中初始化时调用太早(比如 DLL_PROCESS_ATTACH 里),此时 CRT 堆可能还没准备好。
立即学习“C++免费学习笔记(深入)”;