valgrind诊断C/C++内存泄漏

1.valgrind介绍

C/C++中内存分配与管理是程序员比较头疼的事情,大型线上业务系统,系统内存泄漏到一定程序,可能会因为分配不到内存而导致宕机,后果很严重。
valgrind工具大件提供了许多调试和性能分析工具,包含包含七个生产质量工具:一个内存错误检测器,两个线程错误检测器,一个缓存和分支预测探查器,一个生成调用图的缓存和分支预测探查器以及两个不同的堆探查器。还包括一个实验性的SimPoint基本块矢量生成器。
这些工具中最流行的称为Memcheck。它可以检测C和C++程序中常见的许多与内存相关的错误,这些错误可能导致崩溃和不可预测的行为。实际上memcheck使用它自己的内存分配代替标准C中的内存分配(malloc和free),因此可以检测出一些异常信息。

2.安装

我的平台是centos,先来安装valgrind,可以yum安装,也可以代码安装。

yum -y install valgrind

valgrind诊断C/C++内存泄漏_第1张图片
查看内存分配选项:
valgrind诊断C/C++内存泄漏_第2张图片

3.例子

先写一段没有free的代码,运行结果如下。

// save this code as mem_leak_test.cpp
// compile g++ mem_leak_test.cpp -o mem_leak_test -g
// valgrind --tool=memcheck --leak-check=full ./mem_leak_test 
#include 
#include 
#include 

int main(int argc, char** argv)
{
    int size = 10;
    char* buffer = (char*)malloc(sizeof(char) * size);
    buffer[1] = 5;

    return 0;
}

valgrind运行方式为,可以看到有10个byte确认丢失,这是因为没有free造成的。

valgrind --tool=memcheck --leak-check=full ./mem_leak_test

valgrind诊断C/C++内存泄漏_第3张图片
–tools=memcheck表示使用memcheck工具,valgrind默认的工具也是这个,加不加都可以。结果中包含以下信息。

  • HEAP SUMMARY,它表示程序在堆上分配内存的情况,2 allocs表示分配了2次内存,0 frees表示释放了0次,72,714 bytes allocated表示分配了72,714个字节
  • 如果有泄漏,valgrind会报告是哪个位置发生了泄漏(main中cpp第8行)
  • LEAK SUMMARY,表示不同的内存丢失类型
    • definitely loss: 确认丢失,需修复因为在程序运行完的时候,没有指针指向它,指向它的指针在程序中丢失了;
    • indirectly lost: 间接丢失,无须处理,当使用了含有指针成员的类或结构时可能会报这个错误。这类错误无需直接修复,他们总是与"definitely lost"一起出现,只要修复"definitely lost"即可;
    • possibly lost: 可能丢失,需修复,发现了一个指向某块内存中部的指针,而不是指向内存块头部。这种指针一般是原先指向内存块头部,后来移动到了内存块的中部,还有可能该指针和该内存根本就没有关系,检测工具只是怀疑有内存泄漏。
    • still reachable: 可以访问,需修复,未丢失但也未释放。如果程序是正常结束的,那么它可能不会造成程序崩溃。表示泄漏的内存在程序运行完的时候,仍旧有指针指向它,因而,这种内存在程序运行结束之前可以释放。一般情况下valgrind不会报这种泄漏,除非使用了参数 --show-reachable=yes。
    • suppressed:已被解决,无须处理,出现了内存泄露但系统自动处理了;可以无视这类错误。

free后再来valgrind,问题解决。

// save this code as mem_leak_test.cpp
// compile g++ mem_leak_test.cpp -o mem_leak_test -g
// valgrind --tool=memcheck --leak-check=full ./mem_leak_test 
#include 
#include 
#include 

int main(int argc, char** argv)
{
    int size = 10;
    char* buffer = (char*)malloc(sizeof(char) * size);
    buffer[1] = 5;

    if(buffer) {
        free(buffer);
        buffer = NULL;
    }
    return 0;
}

valgrind诊断C/C++内存泄漏_第4张图片
更详细的教程可以参考[1]和[3]

4.参考

[1] https://www.valgrind.org/docs/manual/quick-start.html#quick-start.intro
[2] http://senlinzhan.github.io/2017/12/31/valgrind/
[3] http://www.it.uc3m.es/pbasanta/asng/course_notes/memory_profiler_en.html#memcheck_tool

你可能感兴趣的:(C/C++)