_CrtDumpMemoryLeaks() 不需手动调用,启用 _CRTDBG_LEAK_CHECK_DF 后 CRT 会在 exit 前自动触发检测;需在 main 首行设 _CrtSetDbgFlag,Debug 模式链接 MTd/MDd,并定义 _CRTDBG_MAP_ALLOC 和 new 宏以获取文件行号。
_CrtDumpMemoryLeaks() 在程序退出时自动检测泄漏Windows 下 Visual Studio 自带的 CRT 调试堆能捕获未释放的堆内存,前提是启用调试堆并正确配置。它不依赖外部工具,适合快速验证单次运行是否存在泄漏。
main() 第一行)调用 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG
_LEAK_CHECK_DF);
MTd 或 MDd)_CrtDumpMemoryLeaks() —— 设置了 _CRTDBG_LEAK_CHECK_DF 后,CRT 会在 exit() 前自动触发,此时调用栈信息才完整stdlib.h 前定义 _CRTDBG_MAP_ALLOC,并使用 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
AddressSanitizer(ASan)跨平台抓运行时泄漏Clang 和 GCC 都支持 AddressSanitizer,它不仅能报内存泄漏,还能发现越界读写、UAF 等问题,且无需修改代码,只需编译选项开启。
g++ -g -O1 -fsanitize=address -fno-omit-frame-pointer leak.cpp -o leak
=================================================================
==12345==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 8 byte(s) in 1 object(s) allocated from:
#0 0x7f... in operator new(unsigned long) (libclang_rt.asan.so)
#1 0x56... in main leak.cpp:5LSAN_OPTIONS=detect_leaks=2
valgrind --leak-check=full 在 macOS 上跑不了valgrind 官方长期不支持 macOS(尤其是 10.12+),主因是系统内核机制(KASLR、AMFI、SIP)与 valgrind 的二进制插桩原理冲突。你看到的 Unsupported architecture 或直接崩溃不是配置问题,而是根本不可用。
AddressSanitizer(推荐)或 Xcode 自带的 Leaks 工具(需 Instruments 图形界面 + malloc stack logging 开启)new/delete 运算符做轻量级泄漏统计当项目不允许引入 ASan、又需在 Release 模式下长期监控时,可全局重载分配器,记录地址、大小、调用位置,退出时遍历未匹配的 delete。
::operator new 和 ::operator delete,用 std::unordered_map 存活块(CallSite 含 __FILE__、__LINE__、size)nothrow 版本、数组版本(operator new[])、对齐版本(C++17 operator new(size_t, std::align_val_t)),否则部分分配会绕过统计std::mutex),但锁本身可能引发死锁(比如在构造函数里 new 导致递归加锁),更安全的做法是用 std::atomic_flag 自旋或 TLS 存储待注册项malloc/free、VirtualAlloc 等非 new 分配,也不能反映对象语义泄漏(比如智能指针循环引用)detect_leaks=2”,或者在 macOS 上花半天配 valgrind 却不知道它早就弃疗了。真正有效的起点永远是:先确认泄漏是否真实存在(用 ASan 或 CRT),再决定要不要深入到自定义分配器级别。