vs内存泄漏检测需两步:在main开头加#define _crtdbg_map_alloc、#include 和_crtsetdbgflag(_crtdbg_alloc_mem_df | _crtdbg_leak_check_df),且必须debug模式编译。

VS里怎么开内存泄漏检测开关
默认关着,不手动开就啥也看不到。关键就两步:加头文件、加初始化代码,缺一不可。
- 在主
main()函数最开头(或第一个可能分配内存的位置之前)加上:#define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h>
- 紧跟着加一句:
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); - 注意:必须用 Debug 模式编译运行,Release 下这些宏全被预处理器剔掉,查不到任何东西
为什么只报{1234}不显示文件名和行号
因为没启用调试信息映射,_CrtSetBreakAlloc(1234) 也跳不到对应代码行。
- 确保项目属性 → C/C++ → 常规 → “调试信息格式”设为
Program Database (/Zi)或Program Database for Edit and Continue (/ZI) - 在包含
crtdbg.h的文件顶部,加这行:#ifdef _DEBUG #define new new(_NORMAL_BLOCK, __FILE__, __LINE__) #endif
- 如果用了
std::make_shared或容器扩容,它们内部的 new 可能绕过宏替换,这类泄漏不会带源码定位
_CrtDumpMemoryLeaks() 什么时候调、在哪调
它只在调用时检查当前未释放的块,不是自动监控全程;放错位置会漏报或误报。
- 最稳妥位置是
main()函数末尾return前,此时全局对象已析构、线程已退出,残留才是真泄漏 - 别在局部作用域末尾调用——比如某个函数里
new了但没delete,你提前调用只会看到“还有 1 块”,但不知道谁干的 - 如果程序有多个出口(比如
exit()、异常中途退出),得确保每个路径都走到泄漏检查点,否则部分泄漏会被忽略
常见假阳性:CRT 自己的泄漏和 DLL 延迟加载
启动时 CRT 库和系统 DLL 会做少量内部分配,VS 默认把它们也算进泄漏报告,容易干扰判断。
立即学习“C++免费学习笔记(深入)”;
- 在
_CrtSetDbgFlag()调用前加一行:_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);,避免弹窗打断流程 - 真正要盯的是带
{xxx}编号 + 文件/行号的条目;纯{0}或{1}开头、没源码信息的,大概率是 CRT 初始化块,可忽略 - 如果用了静态链接 CRT(
/MT),泄漏报告更干净;动态链接(/MD)下第三方 DLL 的延迟加载可能触发额外分配,这类不算你的代码问题
真正的难点不在打开工具,而在区分哪些是你的 bug,哪些是环境噪声。多跑几次、比对编号变化、配合断点验证,比单看一次报告有用得多。










