Valgrind 是一个编程工具,用于内存调试、内存泄漏检测以及性能分析。Valgrind 工具集中的 Memcheck 是用于检测内存管理和线程错误的主要工具。
参考:https://blog.csdn.net/weixin_44046545/article/details/138417524
1、安装 Valgrind
sudo apt-get install valgrind # Debian/Ubuntu
sudo yum install valgrind # CentOS/Fedora
2、运行 Valgrind
要使用 Valgrind 检测一个程序的内存泄漏,首先确保你的程序是带调试信息编译的(通常是 -g 编译器选项)。然后,运行以下命令:
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./your_program
其中 ./your_program 是你的可执行文件。
--leak-check=full:进行内存泄漏检测并给出每个泄漏的详细信息。
--show-leak-kinds=all:报告所有类型的内存泄漏。
--track-origins=yes:跟踪未初始化值的来源,有助于发现使用未初始化内存的错误。
3、分析 Valgrind 输出实例
(1)没有内存泄漏的程序
文件:no_leak.cpp
#include <iostream>
int main() {
int* data = new int[10]; // 动态分配内存
for (int i = 0; i < 10; ++i) {
data[i] = i;
}
// 使用完内存后,正确释放内存
delete[] data;
return 0;
}
编译方法
使用下面的命令来编译这个程序,确保包含 -g 选项以便 Valgrind 可以提供关于源代码的详细信息。
g++ -g no_leak.cpp -o no_leak
使用 Valgrind 检测
运行 Valgrind 来检查内存泄漏:
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./no_leak
(2) 有内存泄漏的程序
这个程序同样动态分配内存,但忘记释放内存,从而造成内存泄漏。
文件:has_leak.cpp
#include <iostream>
int main() {
int* data = new int[10]; // 动态分配内存
for (int i = 0; i < 10; ++i) {
data[i] = i;
}
// 忘记释放内存
// delete[] data; // 这行应该被取消注释来避免内存泄漏
return 0;
}
编译方法
同样,使用 -g 选项来编译程序:
g++ -g has_leak.cpp -o has_leak
使用 Valgrind 检测
运行 Valgrind 来检查程序是否有内存泄漏:
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./has_leak
解释输出
- Memcheck, a memory error detector: 这一行表明你正在使用 Memcheck 工具,它是 Valgrind
中用于检测内存错误的一个工具。 - Command: 显示了被检测的命令行。
- HEAP SUMMARY: 总结了程序退出时堆内存的使用情况。
- in use at exit: 程序结束时,仍然有40字节的内存在使用中,没有被释放。
- total heap usage: 程序共申请了2次内存,释放了1次,总共分配了72,704字节的堆内存。
- 40 bytes in 1 blocks are definitely lost:
表示有40字节的内存在一个块中被“绝对丢失”,也就是说这块内存没有被释放且无法再被访问。 - at 0x483C583: 内存分配发生的位置的内存地址。
- operator new[](unsigned long): 内存是通过 new[] 操作符分配的。
- by 0x10919E: 内存分配发生在 has_leak.cpp 的第4行。
- LEAK SUMMARY: 显示了内存泄漏的总结。
- definitely lost: 明确报告了40字节被泄漏。
- indirectly lost: 没有间接丢失的内存。
- possibly lost: 没有可能丢失的内存。
- still reachable: 没有仍可达的内存。
- suppressed: 没有被抑制的错误。
- ERROR SUMMARY: 总结了检测到的错误数。此处显示有1个错误。
此输出表明程序存在内存泄漏,具体来说,是在 has_leak.cpp 文件的第5行通过 new[] 动态分配的40字节内存没有被释放。通过这些详细信息,你可以直接定位到代码中的问题位置并修正它。