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的简单介绍及使用。其实内存检测工具有很多,未来有机会笔者将继续记录。

posted @ 2025-03-18 20:57  AquerKing  阅读(276)  评论(0)    收藏  举报