Ubuntu 系统下使用Valgrind工具进行内存检测
C/C++开发中,我们难免会和指针打交道。指针虽然让许多操作变得极为自由且灵活,但也带来了许多隐患,其中内存泄漏问题尤为严重。因此在实际开发中,常常使用一些辅助工具来提前预防内存泄漏问题。
今天简单介绍一下Valgrind。
首先在Ubuntu操作系统下安装Valgrind(本文使用的是Ubuntu 24.04 LTS)
sudo apt update
sudo apt install valgrind
接下来,便可以准备检测程序了。现在有如下代码:
int main() {
int** arrays = new int*[10];
for (int i = 0; i < 10; i++) {
arrays[i] = new int[10];
}
delete[] arrays;
return 0;
}
使用Valgrind检测。
valgrind ./build/test
得到如下信息。
==11434== Memcheck, a memory error detector
==11434== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==11434== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==11434== Command: ./build/test
==11434==
==11434==
==11434== HEAP SUMMARY:
==11434== in use at exit: 400 bytes in 10 blocks
==11434== total heap usage: 12 allocs, 2 frees, 74,208 bytes allocated
==11434==
==11434== LEAK SUMMARY:
==11434== definitely lost: 400 bytes in 10 blocks
==11434== indirectly lost: 0 bytes in 0 blocks
==11434== possibly lost: 0 bytes in 0 blocks
==11434== still reachable: 0 bytes in 0 blocks
==11434== suppressed: 0 bytes in 0 blocks
==11434== Rerun with --leak-check=full to see details of leaked memory
==11434==
==11434== For lists of detected and suppressed errors, rerun with: -s
==11434== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
可以看到有两个总结:HEAP SUMMARY(堆内存摘要)和LEAK SUMMARY(泄露内存摘要)。
堆内存摘要中指出:程序在退出时仍有10个内存块总计400字节在使用;总共堆内存使用包含了12次申请内存,2次释放,共分配了74,208字节。那么也许读者会疑惑代码其实只有11次申请,1次释放,为什么会多一次。
这里读者可以自行实验:
int main() {
new int;
return 0;
}
以上程序在Valgrind检测得到的信息如下:
==12306== Memcheck, a memory error detector
==12306== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==12306== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==12306== Command: ./build/test
==12306==
==12306==
==12306== HEAP SUMMARY:
==12306== in use at exit: 4 bytes in 1 blocks
==12306== total heap usage: 2 allocs, 1 frees, 73,732 bytes allocated
==12306==
==12306== LEAK SUMMARY:
==12306== definitely lost: 4 bytes in 1 blocks
==12306== indirectly lost: 0 bytes in 0 blocks
==12306== possibly lost: 0 bytes in 0 blocks
==12306== still reachable: 0 bytes in 0 blocks
==12306== suppressed: 0 bytes in 0 blocks
==12306== Rerun with --leak-check=full to see details of leaked memory
==12306==
==12306== For lists of detected and suppressed errors, rerun with: -s
==12306== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
可以看到结果仍然多了1次。因此我们可以推测是由于标准库或运行时所进行的内存申请和释放。
在摘要信息后,Valgrind提示我们使用--leak-check=full选项以查看泄露内存的详情。
==12564== Memcheck, a memory error detector
==12564== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==12564== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==12564== Command: ./build/test
==12564==
==12564==
==12564== HEAP SUMMARY:
==12564== in use at exit: 400 bytes in 10 blocks
==12564== total heap usage: 12 allocs, 2 frees, 74,208 bytes allocated
==12564==
==12564== 400 bytes in 10 blocks are definitely lost in loss record 1 of 1
==12564== at 0x48485C3: operator new[](unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==12564== by 0x109187: main (test.cpp:4)
==12564==
==12564== LEAK SUMMARY:
==12564== definitely lost: 400 bytes in 10 blocks
==12564== indirectly lost: 0 bytes in 0 blocks
==12564== possibly lost: 0 bytes in 0 blocks
==12564== still reachable: 0 bytes in 0 blocks
==12564== suppressed: 0 bytes in 0 blocks
==12564==
==12564== For lists of detected and suppressed errors, rerun with: -s
==12564== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
加上选项后显示出发生内存泄漏的调用栈。同时显示了行号(注意!显示行号需要编译时添加-g选项以附加调试信息)
以上就是对Valgrind的简单介绍及使用。其实内存检测工具有很多,未来有机会笔者将继续记录。

浙公网安备 33010602011771号