--show-leak-kinds合法值为definite、possible、indirect、still-reachable(或逗号分隔组合),以及all;其中definite表示无指针可达的确定泄漏,possible表示可能存在全局指针引用但无法确认,indirect指因其他泄漏导致的间接泄漏,still-reachable表示程序退出时仍有指针可达——该类虽不报错但需人工甄别是否隐含设计缺陷或掩盖真实泄漏。

–show-leak-kinds 支持哪些取值
这个参数只接受几个固定字符串,不是自由填写的。合法值是:definite、possible、indirect、still-reachable,或者用逗号拼接多个,比如 definite,possible;也可以直接写 all 表示全部启用。
不同 leak kind 的实际含义和触发场景
Valgrind 把“没 free 的内存”按可追踪程度分了四类,不是主观判断,而是根据调用栈和指针可达性自动归类:
-
definite:堆上分配的内存,没有任何指针能访问到它了(比如局部指针变量出作用域后未释放) -
possible:存在某个全局/静态指针可能指向它,但 Valgrind 无法 100% 确认(比如通过 void* 转换、函数指针间接操作) -
indirect:本身没泄漏,但它所指向的结构体里有definite泄漏(比如链表头节点被释放,但后续节点没遍历释放) -
still-reachable:程序退出时仍有指针能访问到这块内存(比如全局 vector 里 push_back 的对象),不算 bug,但要人工确认是否该在 exit 前清理
–show-leak-kinds=all 和 –leak-check=full 的关系
这两个参数独立生效,但常一起用:
-
--leak-check=full控制是否显示泄漏的调用栈(行号、函数名),不加它就只告诉你“有泄漏”,但找不到哪行代码 -
--show-leak-kinds=all控制报告里包含哪几类泄漏 —— 即使开了full,默认也只报definite和possible,indirect和still-reachable会被静默忽略 - 所以真想扫全,必须显式加
--show-leak-kinds=all,否则indirect类泄漏根本不会出现在输出里
容易被忽略的细节:still-reachable 不等于安全
很多人看到 still-reachable 就以为“没问题”,其实风险不小:
- 它可能是设计缺陷:比如单例对象在 main 结束后才析构,但析构函数里又调用了已被 dlclose 的库函数
- 它会掩盖真正的
definite泄漏:如果某块内存既被 global 指针引用(变成still-reachable),又被局部指针重复 new 且未 delete(definite),后者可能被前者“带偏”而漏报 - 某些嵌入式或长期运行服务中,
still-reachable内存会持续累积,最终耗尽地址空间











