_CrtDumpMemoryLeaks() 是 Windows 下最轻量的泄漏检测方式,仅需在 main 开头调用 _CrtSetDbgFlag 并启用调试堆,程序退出时自动报告未释放内存,但无调用栈且依赖正常返回。
用
在 Windows 下快速捕获泄漏
Windows 平台下最轻量、无需额外工具的泄漏检测方式,依赖 MSVC 的 CRT 调试堆。它只在程序退出时打印未释放的堆块摘要,不提供调用栈,但胜在开箱即用。
关键点:
必须在程序入口(如
)开头调用
确保使用调试版(
或
),且定义了
泄漏报告中显示的文件名和行号,依赖于在
前定义
若程序有多个出口(如提前
或异常终止),泄漏可能不被触发——需确保正常返回到
末尾
Linux/
mac
OS 下用
定位源头
是跨平台事实标准,但仅适用于 Linux/macOS(macOS Catalina+ 需注意系统限制)。它能精确指出每一块泄漏内存的分配位置,包括函数名、源码行、调用栈。
常见误操作:
立即学习
“
C++免费学习笔记(深入)
”;
Trae win
Trae Windows 官方版本现已全面支持 Win10 和 Win11 系统(64位)。国内开发者可直接访问 Trae 中文官网(trae.cn 或 trae.com.cn),一键下载官方正版 .exe 安装包,享受国内直连的高速稳定体验。安装过程极其简便,双击即可运行,并支持一键无缝导入 VS Code 或 Cursor 的原有主题、快捷键及插件配置。登录支持手机号、微信或稀土掘金账号。内置免费的豆包与 DeepSeek 等顶级大模型,让你开箱即用,轻松开启高效的 AI 智能编程之旅。
下载
未用
编译,导致报告里只有地址没有符号——务必加
忽略
:对“未初始化值”间接导致的泄漏排查很有用
误以为
够用:它只报总数,漏掉具体泄漏点
C++ 异常路径未覆盖:若构造函数抛异常,
分配后未匹配
,valgrind 会如实报告
用
(ASan)在编译期注入运行时检查
Clang/GCC 支持的 ASan 不仅查内存泄漏,还查越界、UAF、栈使用后释放等。相比 valgrind,它更快(约 2× 慢),且支持多线程,适合 CI 或日常开发启用。
启用方式简单,但有几个硬性前提:
必须链接 ASan 运行时:GCC/Clang 默认已包含,但若静态链接或交叉编译需显式加
不能与
共存(二者都劫持 malloc/free)
默认不开启泄漏检测:需额外加
并设置
环境变量
某些 STL 容器(如
的 SSO 优化)可能触发误报,可加
细化控制
为什么 RAII 和智能指针不能完全避免泄漏?
RAII 是 C++ 抗泄漏的核心机制,但真实项目中仍有三类典型漏点:
循环引用:两个对象互相持有对方的
,引用计数永不归零——改用
打破循环
裸指针被临时“托管”但未移交所有权:例如函数返回
出的指针,调用方忘记包装成
全局/静态对象析构顺序不确定:A 的析构函数中访问 B 的静态成员,而 B 已析构,可能导致释放逻辑跳过或崩溃,间接掩盖泄漏
第三方库内部泄漏:比如用了
加载的插件未调用对应
,ASan 和 valgrind 能发现,但无法直接修复
真正难排查的,往往不是
没配
,而是资源生命周期跨越模块边界、析构时机不可控、或工具链本身对某些分配模式(如 mmap、自定义 allocator)无感知。
_CrtDumpMemoryLeaks()main()_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);/MDd/MTd_DEBUG#include _CRTDBG_MAP_ALLOCexit()main#define _CRTDBG_MAP_ALLOC
#include
#include
int main() {
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
int* p = new int[100];
// 忘记 delete[] p;
return 0; // 此处触发检查
}
valgrind --leak-check=fullvalgrind-gg++ -g -O0--track-origins=yes--leak-check=summarynewdeleteg++ -g -O0 leak.cpp -o leak
valgrind --leak-check=full --show-leak-kinds=all ./leakAddressSanitizer-fsanitize=addressvalgrind-fsanitize=address -fno-omit-frame-pointer -gASAN_OPTIONS=detect_leaks=1std::stringdetect_stack_use_after_return=1g++ -fsanitize=address -fno-omit-frame-pointer -g leak.cpp -o leak
ASAN_OPTIONS=detect_leaks=1 ./leakstd::shared_ptrshared_ptrstd::weak_ptrnewunique_ptrdlopendlclosenewdelete