valgrind检查代码内存泄漏,5种内存泄漏情况
摘要:
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种内存泄漏情况的更多相关文章
- 【c++】内存检查工具Valgrind介绍,安装及使用以及内存泄漏的常见原因
转自:https://www.cnblogs.com/LyndonYoung/articles/5320277.html Valgrind是运行在Linux上一套基于仿真技术的程序调试和分析工具,它包 ...
- 使用valgrind检查内存
Valgrind是运行在Linux上一套基于仿真技术的程序调试和分析工具,是公认的最接近Purify的产品,它包含一个内核——一个软件合成的CPU,和一系列的小工具,每个工具都可以完成一项任务——调试 ...
- vld,Bounds Checker,memwatch,mtrace,valgrind,debug_new几种内存泄露检测工具的比较,Valgrind Cheatsheet
概述 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,在大型的.复杂的应用程序中,内存泄漏是常见的问题.当以前分配的一片内存不再需要使用或无法访问时,但是却 ...
- 转: 使用valgrind检查内存问题
作者:gfree.wind@gmail.com 博客:blog.focus-linux.net linuxfocus.blog.chinaunix.net 本文的copyleft归gfree ...
- [C]C语言中的指针和内存泄漏几种情况
引言 原文地址:http://www.cnblogs.com/archimedes/p/c-point-memory-leak.html,转载请注明源地址. 对于任何使用C语言的人,如果问他们C语言的 ...
- C语言中的指针和内存泄漏几种情况
引言 原文地址:http://www.cnblogs.com/archimedes/p/c-point-memory-leak.html,转载请注明源地址. 对于任何使用C语言的人,如果问他们C语言的 ...
- 用valgrind检查内存问题
Valgrind Valgrind作为一个免费且优秀的工具包,平时大部分人可能都是使用valgrind检测内存问题,如内存泄露,越界等. Valgrind工具包包含多个工具,如Memcheck,Cac ...
- JavaScript如何工作:垃圾回收机制 + 常见的4种内存泄漏
原文地址: How JavaScript works: memory management + how to handle 4 common memory leaks 本文永久链接:https://d ...
- 使用valgrind进行内存泄漏和非法内存操作检测
valgrind是一个强大的工具,最常用的功能是用它来检测内存泄漏和非法内存的使用.要想让valgrind报告的更加细致,请使用-g进行编译. 基本命令如下: $ valgrind --tool=me ...
随机推荐
- JPA測试实例
依赖架包 实体 import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.G ...
- 【uoj35】后缀排序
后缀数组模板题 #include<algorithm> #include<cstdlib> #include<cstring> #include<cstdio ...
- HTTP要点概述:六,HTTP报文
一,HTTP报文: 用于HTTP交互的信息称为HTTP报文.请求端(客户端)的HTTP报文叫做请求报文,响应端(服务器)的叫做响应报文.HTTP报文本身是由多行(用CR+LF换行)数据构成的字符串文本 ...
- [RK3288][Android6.0] 系统按键驱动流程分析【转】
本文转载自:http://blog.csdn.net/kris_fei/article/details/77894406 Rockchip的按键驱动位于 kernel/drivers/input/ke ...
- 9 Range 实用操作
9.1 剪切.复制和粘贴来移动数据 sourceRange.Cut [Destination] 如果指定Destination,相当于Ctrl^X(sourceRange) & Ctrl^V( ...
- ASP.Net 下载大文件的实现 (转)
原文:http://www.cnblogs.com/luisliu/p/4253815.html 当我们的网站需要支持下载大文件时,如果不做控制可能会导致用户在访问下载页面时发生无响应,使得浏览器崩溃 ...
- [Swift]Array(数组)扩展
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- Android 性能优化(15)网络优化( 11)Manipulating Broadcast Receivers On Demand
Manipulating Broadcast Receivers On Demand This lesson teaches you to Toggle and Cascade State Chang ...
- Spring.Net学习笔记(八)-设置配置文件参数
一.开发环境 VS2013 .netframework4.5 spring.net1.3.1 二.项目结构 三.开发过程 1.编写Person类 namespace SpringNetConfigAr ...
- can't set blob value on that column
MySQL_Prepared_Statement::setBlob: can't set blob value on that column, MySQL error code:0, SQLState ...