1 Valgrind 简介
Valgrind 是一个用于内存调试、内存泄露检测和性能分析的工具,主要用于Linux平台,可以帮助开发者检测 C/C++程序中的各种内存错误:
内存泄露(Memory Leak)
访问未分配的内存(Invalid Memory Access)
访问已经释放的内存(Use After Free)
数组越界(Array Overrun)
使用未初始化的内存(Uninitialized Memory)
Valgrind将内存泄漏分为4类:
明确泄漏(definitely lost):内存还没释放,但已经没有指针指向内存,内存已经不可访问。
间接泄漏(indirectly lost):泄漏的内存指针保存在明确泄漏的内存中。由于明确泄漏的内存不可访问,间接泄漏的内存也不可访问。
可能泄漏(possibly lost):指针并不指向内存头地址,而是指向内存内部的位置。
仍可访达(still reachable):指针一直存在且指向内存头部,直至程序退出时内存还没释放。
2 安装
valgrind是一个linux命令行工具,直接安装即可。
sudo apt update
sudo apt install valgrind用户手册:Valgrind User Manual
3 Valgrind memcheck 使用方法
Memcheck: a memory error detector.
参数示例:
valgrind --log-file=valgrind.log \
--tool=memcheck \
--leak-check=full \
--show-reachable=yes (equal to `--show-leak-kinds=all`) \
--leak-resolution=low \
./test-app arg1 arg2 参数解释:
--log-file:指定valgrind日志保存位置
--tool:指定使用memcheck工具
--leak-check:指定如何报告内存泄漏
no:没有输出
summary:只输出统计的结果
full:输出详细内容
--show-reachable:--show-reachable=yes等效于--show-leak-kinds=all,显示所有内存泄漏类型
--leak-resolution:-leak-resolution=low,日志中合并相似的泄漏记录
3.1 检测内存泄露
测试代码:
#include <stdlib.h>
int main(int argc, const char *argv[]) {
int *array = malloc(sizeof(int)); // 申请了内存,但没有释放
return 0;
}编译指令:
gcc -g test-demo.c -o test-demo检测程序:
valgrind --log-file=valgrind.log --tool=memcheck --leak-check=full --show-reachable=yes --leak-resolution=low ./test-demo输出:

日志分析:
HEAP SUMMARY 表示堆上内存分配的情况,1 allocs表示分配了1次内存,0 frees表示没有释放内存;
提示用户程序出现了明确泄漏(definitely lost),代码位置 main (test-demo.c:4);
3.2 检测内存间接丢失
测试代码:
#include <stdio.h>
#include <stdlib.h>
struct list {
int value;
struct list *next;
};
int main(int argc, const char *argv[]) {
struct list *root;
root = (struct list *)malloc(sizeof(struct list));
root->next = (struct list *)malloc(sizeof(struct list));
printf("root: %p, roop->next: %p\n", root, root->next);
root = NULL; // 丢失root指针,导致root存储的next指针成为了间接泄漏
return 0;
}编译指令:
gcc -g test-demo.c -o test-demo检测程序:
valgrind --log-file=valgrind.log --tool=memcheck --leak-check=full --show-reachable=yes --leak-resolution=low ./test-demo输出:

日志分析:
HEAP SUMMARY 表示堆上内存分配的情况,3 allocs表示分配了3次内存,1 frees表示释放了1次内存
提示用户程序出现了间接泄漏(indirectly lost),代码位置 main (test-demo.c:13)
提示用户程序出现了明确泄漏(definitely lost),代码位置 main (test-demo.c:12)
3.3 检测内存越界访问
测试代码:
#include <iostream>
#include <vector>
int main(int argc, const char *argv[]) {
std::vector<int> v(10, 0);
std::cout << v[10] << std::endl;
return 0;
}编译指令:
g++ -g test-demo.cc -o test-demo检测程序:
valgrind --log-file=valgrind.log --tool=memcheck --leak-check=full --show-reachable=yes --leak-resolution=low ./test-demo输出:

日志分析:
Invalid read of size 表示内存越界访问,代码位置 main (test-demo.cc:6)
评论区