definitely lost 是确定性内存泄露,表明指针丢失且内存不可达,需优先检查 Valgrind 报告的调用栈末行源码;still reachable 非泄露但可能暴露缓存膨胀或循环引用问题。

Valgrind 报 definitely lost 是真泄露,别急着改代码
看到 definitely lost 就说明有指针丢了、没 free/delete,而且这块内存彻底不可达了。不是误报,也不是“可能有问题”,是确定性泄露。这时候别怀疑 Valgrind,先盯死它给出的调用栈——尤其是最后一行你自己的源码位置。
常见错误现象:new 但没 delete;malloc 但没 free;异常路径绕过了清理逻辑;容器(如 std::vector)里存了裸指针却没手动释放。
- 运行命令必须加
--leak-check=full --show-leak-kinds=definite,possible,否则默认只报 definite,漏掉潜在问题 - 编译时加
-g,否则 Valgrind 只能显示汇编地址,找不到你写的哪一行 - 如果程序跑完立刻退出,Valgrind 才能完整扫描;后台常驻进程得用
--tool=memcheck --time-stamp=yes配合信号触发检查
still reachable 不算泄露,但可能是设计隐患
still reachable 意思是:内存还被某个全局/静态变量、或栈上活着的指针指着,理论上还能访问到。Valgrind 不认为这是泄露,但现实中它常暴露两类问题:全局缓存没做容量限制,或单例对象在 main 结束前没显式销毁。
使用场景:日志缓冲区、配置解析后缓存的 std::string、插件系统里注册的回调函数表。
立即学习“C++免费学习笔记(深入)”;
- 若
still reachable内存随运行时间线性增长,大概率是缓存泄漏,不是“没关系” - C++ 中
std::shared_ptr循环引用也会表现为still reachable,因为控制块还在,但对象实际已无法访问 - Valgrind 默认不追踪
mmap分配的大块内存(如某些 STL 实现的堆池),这类需结合--track-origins=yes看分配源头
用 valgrind --tool=memcheck --suppressions=mysupp.supp 过滤第三方库噪音
刚跑 Valgrind 就刷出几百行 Qt、Boost 或 glibc 的 still reachable,不是你的锅,是这些库内部管理策略导致的。硬看只会干扰判断。
实操建议:用 --gen-suppressions=all 先生成压制规则,再挑出真正属于你代码的几条保留,其余导出到 mysupp.supp。
- 压制文件里必须包含
fun:行匹配函数名,比如fun:QApplication::exec,不能只压obj:/usr/lib/x86_64-linux-gnu/libQt5Core.so.5 - 不要直接用
--suppressions=default.supp,系统自带的压制集过时且不精准,容易漏掉你自己的问题 - CI 流水线里加压制文件后,记得把
--error-exitcode=1保留,确保真正泄露仍会失败
Valgrind 在 C++11 后要特别注意 std::unique_ptr 和 move 语义
Valgrind 看不到 RAII 对象的生命周期,它只跟踪 malloc/free/new/delete 调用。所以 std::unique_ptr 正常转移后,原始指针变空,Valgrind 却可能还在原地址标记“still reachable”,直到析构发生——而析构时机取决于作用域和 move 是否真正发生。
容易踩的坑:把 unique_ptr 存进容器后又用 std::move 赋值给另一个变量,原容器元素变成空,但 Valgrind 的报告可能让你误以为那块内存“丢了”。
- 确认 move 是否生效:打印
ptr.get() == nullptr,别只信语义 - 避免在 lambda 捕获列表里用
[ptr = std::move(ptr)]后继续用原变量,这种写法在部分编译器下可能未定义行为,Valgrind 抓不住,但会引发崩溃 - 对
std::make_unique分配的内存,Valgrind 仍会归为new类型,但调用栈可能只显示模板实例化路径,得往回翻几层才能看到你调用make_unique的那行
最麻烦的情况是泄露发生在 shared library 加载期间,或者 dlopen/dlsym 动态调用路径里——Valgrind 默认不追踪这些,得加 --trace-redir=yes 并配合 --log-file 看重定向细节。这时候调用栈经常断在 __libc_dlopen_mode,得自己顺藤摸瓜。










