摘要:

valgrind是linux下用于调试程序和查找内存泄露的常用工具。valgrind会报告5种内存泄露,"definitely lost", "indirectly lost", "possibly lost", "still reachable", and "suppressed"。笔者于工作闲暇之余对这5种(其实是4种,有一种没研究出结果)内存泄露的出现原因及区别进行了研究,撰此文以记之。

官方解释及分析:

摘自http://valgrind.org/docs/manual/faq.html#faq.deflost

5.2.With Memcheck's memory leak detector, what's the difference between "definitely lost", "indirectly lost", "possibly lost", "still reachable", and "suppressed"?

The details are in the Memcheck section of the user manual.

In short:

  • "definitely lost" means your program is leaking memory -- fix those leaks!
  • "indirectly lost" means your program is leaking memory in a pointer-based structure. (E.g. if the root node of a binary tree is "definitely lost", all the children will be "indirectly lost".) If you fix the "definitely lost" leaks, the "indirectly lost" leaks should go away.
  • "possibly lost" means your program is leaking memory, unless you're doing unusual things with pointers that could cause them to point into the middle of an allocated block; see the user manual for some possible causes. Use --show-possibly-lost=no if you don't want to see these reports.
  • "still reachable" means your program is probably ok -- it didn't free some memory it could have. This is quite common and often reasonable. Don't use --show-reachable=yes if you don't want to see these reports.
  • "suppressed" means that a leak error has been suppressed. There are some suppressions in the default suppression files. You can ignore suppressed errors.

translate

  • "definitely lost":确认丢失。程序中存在内存泄露,应尽快修复。当程序结束时如果一块动态分配的内存没有被释放且通过程序内的指针变量均无法访问这块内存则会报这个错误。

  • "indirectly lost":间接丢失。当使用了含有指针成员的类或结构时可能会报这个错误。这类错误无需直接修复,他们总是与"definitely lost"一起出现,只要修复"definitely lost"即可。例子可参考我的例程。

  • "possibly lost":可能丢失。大多数情况下应视为与"definitely lost"一样需要尽快修复,除非你的程序让一个指针指向一块动态分配的内存(但不是这块内存起始地址),然后通过运算得到这块内存起始地址,再释放它。例子可参考我的例程。当程序结束时如果一块动态分配的内存没有被释放且通过程序内的指针变量均无法访问这块内存的起始地址,但可以访问其中的某一部分数据,则会报这个错误。

  • "still reachable":可以访问,未丢失但也未释放。如果程序是正常结束的,那么它可能不会造成程序崩溃,但长时间运行有可能耗尽系统资源,因此笔者建议修复它。如果程序是崩溃(如访问非法的地址而崩溃)而非正常结束的,则应当暂时忽略它,先修复导致程序崩溃的错误,然后重新检测。

  • "suppressed":已被解决。出现了内存泄露但系统自动处理了。可以无视这类错误。这类错误我没能用例程触发,看官方的解释也不太清楚是操作系统处理的还是valgrind,也没有遇到过。所以无视他吧~

测试程序:

源码(C++):

#include "stdio.h"
#include "stdlib.h" class c1
{
private:
char *m_pcData; public:
c1();
~c1();
}; c1::c1()
{
m_pcData=(char*)malloc(10);
} c1::~c1()
{
if(m_pcData) delete m_pcData;
} char *Fun1()//definitely lost
{
char *pcTemp; pcTemp=(char*)malloc(10);
return pcTemp;
} char *Fun2()//still reachable
{
static char *s_pcTemp=NULL; if(s_pcTemp==NULL) s_pcTemp=(char*)malloc(10); return NULL;
} char *Fun3()//possibly lost
{
static char *s_pcTemp;
char *pcData; pcData=(char*)malloc(10);
s_pcTemp=pcData+1; return NULL;
} int Fun4()//definitely and indirectly lost
{
c1 *pobjTest; pobjTest=new c1(); return 0;
} char *Fun5()//possibly lost but no need of repair,repair the breakdown then no memory leak
{
char *pcData;
int i,*piTemp=NULL; pcData=(char*)malloc(10);
pcData+=10;
for(i=0;i<10;i++)
{
pcData--;
*pcData=0; if(i==5) *piTemp=1;//create a breakdown
}
free(pcData); return NULL;
} int main()
{
printf("This program will create various memory leak,use valgrind to observe it.\n");
printf("Following functions are bad codes,don\'t imitate.\n");
printf("Fun1\n");
Fun1();
printf("Fun2\n");
Fun2();
printf("Fun3\n");
Fun3();
printf("Fun4\n");
Fun4();
printf("Fun5\n");
Fun5();
printf("end\n"); return 0;
}

使用valgrind运行结果:

[root@localhost valtest]# valgrind --tool=memcheck --leak-check=yes ./valtest
==29240== Memcheck, a memory error detector
==29240== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==29240== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==29240== Command: ./valtest
==29240==
This program will create various memory leak,use valgrind to observe it.
Following functions are bad codes,don't imitate.
Fun1
Fun2
Fun3
Fun4
Fun5
==29240== Invalid write of size 4
==29240== at 0x4007BE: Fun5() (main.cpp:73)
==29240== by 0x40086E: main (main.cpp:93)
==29240== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==29240==
==29240==
==29240== Process terminating with default action of signal 11 (SIGSEGV)
==29240== Access not within mapped region at address 0x0
==29240== at 0x4007BE: Fun5() (main.cpp:73)
==29240== by 0x40086E: main (main.cpp:93)
==29240== If you believe this happened as a result of a stack
==29240== overflow in your program's main thread (unlikely but
==29240== possible), you can try to increase the size of the
==29240== main thread stack using the --main-stacksize= flag.
==29240== The main thread stack size used in this run was 10485760.
==29240==
==29240== HEAP SUMMARY:
==29240== in use at exit: 58 bytes in 6 blocks
==29240== total heap usage: 6 allocs, 0 frees, 58 bytes allocated
==29240==
==29240== 10 bytes in 1 blocks are possibly lost in loss record 2 of 6
==29240== at 0x4A05E1C: malloc (vg_replace_malloc.c:195)
==29240== by 0x4006D9: Fun3() (main.cpp:46)
==29240== by 0x400850: main (main.cpp:89)
==29240==
==29240== 10 bytes in 1 blocks are possibly lost in loss record 3 of 6
==29240== at 0x4A05E1C: malloc (vg_replace_malloc.c:195)
==29240== by 0x400795: Fun5() (main.cpp:66)
==29240== by 0x40086E: main (main.cpp:93)
==29240==
==29240== 10 bytes in 1 blocks are definitely lost in loss record 5 of 6
==29240== at 0x4A05E1C: malloc (vg_replace_malloc.c:195)
==29240== by 0x40072D: Fun1() (main.cpp:28)
==29240== by 0x400832: main (main.cpp:85)
==29240==
==29240== 18 (8 direct, 10 indirect) bytes in 1 blocks are definitely lost in loss record 6 of 6
==29240== at 0x4A0666E: operator new(unsigned long) (vg_replace_malloc.c:220)
==29240== by 0x4007F0: Fun4() (main.cpp:56)
==29240== by 0x40085F: main (main.cpp:91)
==29240==
==29240== LEAK SUMMARY:
==29240== definitely lost: 18 bytes in 2 blocks
==29240== indirectly lost: 10 bytes in 1 blocks
==29240== possibly lost: 20 bytes in 2 blocks
==29240== still reachable: 10 bytes in 1 blocks
==29240== suppressed: 0 bytes in 0 blocks
==29240== Reachable blocks (those to which a pointer was found) are not shown.
==29240== To see them, rerun with: --leak-check=full --show-reachable=yes
==29240==
==29240== For counts of detected and suppressed errors, rerun with: -v
==29240== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 4 from 4)
段错误

valgrind检查代码内存泄漏,5种内存泄漏情况的更多相关文章

  1. 【c++】内存检查工具Valgrind介绍,安装及使用以及内存泄漏的常见原因

    转自:https://www.cnblogs.com/LyndonYoung/articles/5320277.html Valgrind是运行在Linux上一套基于仿真技术的程序调试和分析工具,它包 ...

  2. 使用valgrind检查内存

    Valgrind是运行在Linux上一套基于仿真技术的程序调试和分析工具,是公认的最接近Purify的产品,它包含一个内核——一个软件合成的CPU,和一系列的小工具,每个工具都可以完成一项任务——调试 ...

  3. vld,Bounds Checker,memwatch,mtrace,valgrind,debug_new几种内存泄露检测工具的比较,Valgrind Cheatsheet

    概述 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,在大型的.复杂的应用程序中,内存泄漏是常见的问题.当以前分配的一片内存不再需要使用或无法访问时,但是却 ...

  4. 转: 使用valgrind检查内存问题

    作者:gfree.wind@gmail.com 博客:blog.focus-linux.net   linuxfocus.blog.chinaunix.net    本文的copyleft归gfree ...

  5. [C]C语言中的指针和内存泄漏几种情况

    引言 原文地址:http://www.cnblogs.com/archimedes/p/c-point-memory-leak.html,转载请注明源地址. 对于任何使用C语言的人,如果问他们C语言的 ...

  6. C语言中的指针和内存泄漏几种情况

    引言 原文地址:http://www.cnblogs.com/archimedes/p/c-point-memory-leak.html,转载请注明源地址. 对于任何使用C语言的人,如果问他们C语言的 ...

  7. 用valgrind检查内存问题

    Valgrind Valgrind作为一个免费且优秀的工具包,平时大部分人可能都是使用valgrind检测内存问题,如内存泄露,越界等. Valgrind工具包包含多个工具,如Memcheck,Cac ...

  8. JavaScript如何工作:垃圾回收机制 + 常见的4种内存泄漏

    原文地址: How JavaScript works: memory management + how to handle 4 common memory leaks 本文永久链接:https://d ...

  9. 使用valgrind进行内存泄漏和非法内存操作检测

    valgrind是一个强大的工具,最常用的功能是用它来检测内存泄漏和非法内存的使用.要想让valgrind报告的更加细致,请使用-g进行编译. 基本命令如下: $ valgrind --tool=me ...

随机推荐

  1. JSON参数

    JSON(JavaScript Object Notation,JavaScript 对象表示法),多么简单,不就是键值对嘛. 可是每次在前后端之间通过json作为参数传递,我都心烦意乱,甚至吓到面无 ...

  2. ABAP OLE

    OLE DATA: excel TYPE ole2_object, workbook TYPE ole2_object, sheet TYPE ole2_object, cell TYPE ole2_ ...

  3. caioj1472: 后缀自动机1:多个串的LCS

    子串母串跑合并答案 一个点的fail的dep是比任意一条根到这个点路径长度要小的. 那么改就可以直接来了. #include<cstdio> #include<iostream> ...

  4. Spring实战笔记

    晚上看了这本书的前面几章,记录一下自己看到的要点. 全书分为四大部分,Spring核心,web,后台相关,与其它框架集成.今天主要看了第一部分. Spring最根本的使命是简化Java开发,全方位的简 ...

  5. Jquery ajax json 值回传不了

    今天调试系统的时候,MVC 框架下调用ajax 值,回传的json值获取不到,后来发现竟然是服务没开,郁闷不已,留个截图,做个纪念.

  6. Spark 决策树--回归模型

    package Spark_MLlib import org.apache.spark.ml.Pipeline import org.apache.spark.ml.evaluation.Regres ...

  7. 3-1 todolist功能开发

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. java笔记线程方式1线程终端与停止

    public final void stop():让线程停止,过时了,但是还可以使用.public void interrupt():中断线程. 把线程的状态终止,并抛出一个InterruptedEx ...

  9. Rails5 View Document

    更新: 2017/06/11 更新: 2017/06/15 加粗,submit必须放在form_for内部 更新: 2017/06/23 对待完成的追加# TODO:                 ...

  10. CF17C Balance

    题意 [题目描述] 一个仅由a,b,c三种字符组成的字符串,可以对其进行如下两种操作: 选择两个相邻字符,将第一个字符替换成第二个. 选择两个相邻字符,将第二个字符替换成第一个. 这样,通过任意多次的 ...