still reachable 不是严格意义上的内存泄漏,但不可放任不管:它表示程序退出时仍有有效指针指向未释放内存,操作系统会回收,但若出现在循环接口、非全局作用域或伴随资源句柄(如 file*、mutex),则属真实隐患,需结合 --show-reachable=yes 定位源码行号排查。

Still reachable 是不是内存泄漏
不是严格意义上的内存泄漏,但不等于可以放任不管。still reachable 表示:程序退出时,那块内存仍有至少一个有效指针能访问到它,只是没显式 free 或 delete。操作系统会在进程结束时回收,所以不会导致崩溃或长期驻留——但这只对单次运行成立。
哪些 still reachable 可以忽略
以下情况通常无需修复:
-
static std::vector<int></int>、static std::string等全局/静态容器在main返回前未清空(Valgrind 会报告still reachable,但这是 C++ 运行时正常行为) - 第三方库初始化阶段分配的资源(如
libcurl、OpenSSL的全局上下文),只要没反复调用初始化函数,一般安全 - 程序生命周期内只初始化一次、且明确依赖“进程退出时自动清理”的设计(比如某些嵌入式或短命工具)
哪些 still reachable 必须查
这些是真实隐患,容易被当成“无害”而漏掉:
- 在循环中反复调用的接口里出现
still reachable—— 比如每次处理一个请求都fopen日志文件但没fclose,Valgrind 报的still reachable实际是文件描述符 + 缓冲区内存累积泄漏 - 使用
--show-reachable=yes后,堆栈指向你自己的代码(例如某次malloc后忘了free,或new后没delete),尤其出现在非全局作用域(如函数局部、类成员) - 和资源句柄混用:除了内存,
still reachable还可能掩盖未关闭的FILE*、pthread_mutex_t、timerfd等,它们不占 heap 但耗系统资源
怎么快速判断 still reachable 是否危险
别只看 summary 行。关键操作是加两个参数重跑:
valgrind --leak-check=full --show-reachable=yes ./my_program
然后关注输出中是否包含:
- 你的源文件名和具体行号(如
at 0x1092AB: open_log_file (logger.cpp:42)) - 分配点(
malloc/new)和疑似遗漏释放点(比如有open_log_file却没对应close_log_file) - 重复出现的相同地址或相似大小块(暗示循环泄漏)
真正难缠的从来不是 definitely lost——它报得明确;而是那些藏在 still reachable 里的资源管理疏忽,尤其当它和文件、锁、socket 绑定时,不修迟早出问题。











