You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Valgrind Memcheck工具解析四类内存泄漏类型

Valgrind内存泄漏类型全解析:Directly Lost/Indirectly Lost/Still Reachable/Possibly Lost

咱今天就借着你提供的代码实例,把Valgrind里这四种常见的内存泄漏标记给讲透,每个类型都结合代码和检测结果来分析,保证你能get到本质区别。


示例1:Possibly Lost的场景

示例代码

#include<stdio.h> 
#include <stdlib.h>

main() { 
    int *p, i; 
    p = malloc(10*sizeof(int)); 
    for(i = 0;i < 10;i++) 
        p[i] = i; 
    //free(p); 
    printf("Freed\n "); 
}

Valgrind检测结果

LEAK SUMMARY:
==31770== definitely lost: 0 bytes in 0 blocks
==31770== indirectly lost: 0 bytes in 0 blocks
==31770== possibly lost: 20 bytes in 1 blocks
==31770== still reachable: 0 bytes in 0 blocks
==31770== suppressed: 0 bytes in 0 blocks

解析

这里标记的Possibly lost(可能泄漏),是Valgrind没法100%确认这块内存是否真的无法被程序访问。通常这种情况出现在:指针指向了堆内存块的中间位置(而非分配时的起始地址),或者程序中存在一些模糊的指针引用(比如指针被局部修改后,Valgrind的追踪链断裂)。在这个例子里,虽然p本身还在栈上,但可能因为循环赋值的操作,Valgrind的追踪逻辑产生了不确定性,所以标记为“可能泄漏”——本质上这块内存确实没被释放,但Valgrind没法绝对确定它已经完全不可达。


示例2:Still Reachable vs Definitely Lost的对比

场景1:无printf语句

示例代码

main() { 
    int *p, i; 
    p = malloc(10*sizeof(int)); 
    // printf("freed"); 
}

Valgrind检测结果

LEAK SUMMARY:
==14950== definitely lost: 0 bytes in 0 blocks
==14950== indirectly lost: 0 bytes in 0 blocks
==14950== possibly lost: 0 bytes in 0 blocks
==14950== still reachable: 40 bytes in 1 blocks
==14950== suppressed: 0 bytes in 0 blocks

场景2:取消注释printf语句

示例代码

main() { 
    int *p, i; 
    p = malloc(10*sizeof(int)); 
    printf("freed"); 
}

Valgrind检测结果

LEAK SUMMARY:
==15889== definitely lost: 40 bytes in 1 blocks
==15889== indirectly lost: 0 bytes in 0 blocks
==15889== possibly lost: 0 bytes in 0 blocks
==15889== still reachable: 0 bytes in 0 blocks
==15889== suppressed: 0 bytes in 0 blocks

解析

这两个场景的核心区别在于程序结束时,指针p是否还在Valgrind的可达范围内:

  1. Still reachable(仍可访问):场景1中,因为没有调用printf,栈帧里的p指针在程序退出前一直保持有效,Valgrind能追踪到这个指针还指向那块malloc的内存。这种情况严格来说不算“泄漏”——因为程序退出后操作系统会自动回收所有内存,但它提醒你:你没有主动释放你分配的内存,这在长期运行的程序(比如服务器)里会导致内存累积。
  2. Definitely lost(直接泄漏):场景2中,调用printf后,栈帧被修改(或者编译器优化导致p的地址被覆盖),程序结束时Valgrind已经找不到任何指向这块内存的有效指针了。这是100%的内存泄漏——程序运行期间这块内存再也无法被访问,也没被释放,会一直占用内存直到程序退出。

四种内存泄漏类型的核心定义总结

  • Definitely lost(直接泄漏):Valgrind能完全确认,程序中已经没有任何指针指向这块堆内存,且内存从未被释放。这是最严重的泄漏类型,必须修复。
  • Indirectly lost(间接泄漏):通常和复杂数据结构(比如链表、结构体)相关。比如你分配了一个链表节点,节点内部又malloc了一块内存,然后你丢失了节点的指针——此时节点内部的内存就是间接泄漏。简单说:你丢了“容器”的指针,导致容器里的内存也没法访问和释放。
  • Still reachable(仍可访问):程序退出时,还有有效指针指向这块内存,但你没主动调用free。短期运行的程序里这个问题不大,但长期运行的服务必须处理,否则内存会持续增长。
  • Possibly lost(可能泄漏):Valgrind的追踪逻辑无法100%确认内存是否不可达,比如指针指向了内存块的中间位置,或者存在模糊的引用。这种情况需要你结合代码排查,确认是否真的是泄漏。

内容的提问来源于stack exchange,提问作者himsikha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:04:13