Valgrind 是 Linux 下最强大的内存调试工具,无需修改代码即可检测内存泄漏、越界访问和未初始化读取。本文通过 4 个典型场景演示定位流程。
一、安装与基本用法
sudo apt install valgrind valgrind --leak-check=full ./your_program
常用参数组合:
--leak-check=full— 显示每个泄漏块的详细调用栈--show-leak-kinds=all— 显示 definitely/indirectly/possibly/reachable 所有类型--track-origins=yes— 追踪未初始化值的来源
二、场景 1: definitely lost(确定泄漏)
分配了内存但没有任何指针指向它,这是最常见的泄漏类型。
void leak1(void) { int *p = malloc(sizeof(int) * 10); p = NULL; /* 原内存丢失,无法 free */ }
Valgrind 报告:
==1234== 40 bytes in 1 blocks are definitely lost ==1234== at 0x4C2E80F: malloc (vg_replace_malloc.c:...) ==1234== by 0x4005E6: leak1 (main.c:5) ==1234== by 0x40060A: main (main.c:12)
三、场景 2:invalid write(越界写入)
void overflow(void) { int *p = malloc(sizeof(int) * 5); p[5] = 100; /* 越界!有效下标 0~4 */ free(p); }
Valgrind 会报告 Invalid write of size 4,并指出实际分配了 20 字节,但写入了偏移 20 的位置。
四、场景 3:use after free(释放后使用)
void uaf(void) { int *p = malloc(sizeof(int)); *p = 42; free(p); printf("%d\n", *p); /* 使用已释放内存 */ }
五、场景 4:double free(重复释放)
void double_free(void) { int *p = malloc(sizeof(int)); free(p); free(p); /* 重复释放,可能导致崩溃 */ }
六、Suppressions 规则
对于第三方库的已知"假泄漏",可以编写 suppressions 文件过滤:
{
known_lib_leak
Memcheck:Leak
match-leak-kinds: reachable
...
}
使用
valgrind --gen-suppressions=yes 自动生成 suppression 规则,保存到 .supp 文件后通过 --suppressions=file.supp 加载。