definitely lost 必须优先修复,因其内存已彻底失联、无法回收且持续累积;indirectly lost 是其连锁反应,需溯源至首个 definitely lost 点;still reachable 多为设计选择,通常可暂缓,但动态场景下可能隐含资源管理风险。

“definitely lost” 必须优先修,“still reachable” 通常可以暂缓
Valgrind 报告的泄漏类型直接对应修复优先级,不是靠经验猜,而是看它分类字段本身。
看 definitely lost 行就足够判断
只要报告里出现 definitely lost,说明那块内存已经彻底失联:没指针指向它、无法释放、程序退出后也收不回来。这类泄漏每次运行都会累积,哪怕只漏 8 字节,跑上几天也可能吃光几十 GB 内存。
常见触发场景:
- 局部指针变量分配内存后被覆盖(比如
p = malloc(1024); p = malloc(512);,第一次的地址丢了) - 结构体成员指针未在析构/清理函数中释放
- 异常路径绕过了
free或delete(比如中间return、抛异常、goto跳过释放段)
indirectly lost 是 definitely lost 的连锁反应
它本身不新增泄漏点,只是“被带崩”的子节点。比如链表头节点 definitely lost,所有后续节点自动变成 indirectly lost。你修掉头节点的泄漏,整条链的 indirectly lost 就会消失。
不要单独去“修” indirectly lost —— 它是症状,不是病根。顺着调用栈往回找第一个 definitely lost 的分配点,那里才是关键。
still reachable 多数是设计选择,不是 bug
这类内存一直有合法指针持有,直到程序退出才没释放。典型例子:
- 全局/静态容器(如
std::map<int, std::string> g_cache;)在main返回前没清空 - 单例对象内部缓存,在进程生命周期内一直有效
- main 函数末尾的
malloc没free,但指针还活着
它们不导致内存持续增长,也不影响长期运行稳定性。除非你明确要求“零泄漏报告”,否则这类可以标记为已知、暂不处理。
真正容易被忽略的是:有些 still reachable 其实是资源管理疏漏——比如本该在模块卸载时释放的配置缓存,却依赖进程退出自动回收。这种“看起来安全”的设计,在动态加载/热更新场景下会出问题。


















