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 ...
随机推荐
- aarch64-linux-gnu交叉编译Qt4.7.3
到 Qt 官网下载合适的 Qt 版本,地址:http://download.qt-project.org/archive/qt/ 1.环境搭建: 1.安装automake.libtool 和主机上的 ...
- zabbix如何添加主机监控
1,首先,监控的主机安装zabbix客户端.zabbix提供多种监控方式,我们这里监控的主机上边安装agentd守护端进行数据收集并监测. 其中客户端安装我们这里就不介绍了,请参考之前教程里边的客户端 ...
- docker 基本指令
sudo docker info 查看docker状态. jiqing@ThinkPad:~$ sudo docker info [sudo] password for jiqing: Contain ...
- javaSE基础(二)
文件:文件是信息在计算机上的保存形式. 可控式异常:一种必须被处理或必须在可能产生异常的方法中给出声明的异常. 可控式异常的三种处理方式: 1)try...catch捕获 2)throws语句往上抛 ...
- hdoj--1716--排列2(暴力水题)
排列2 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- python-----模糊搜索文件
告诉计算机文件在哪 → 使用路径描述位置 描述文件的特征 → 用条件判断来筛选 比对后打印文件名 → 用循环来实现逐个比对 #!/usr/bin/env python # -*- codi ...
- 洛谷P3690 LCT模板
题目:https://www.luogu.org/problemnew/show/P3690 自己竟然从没有钻研过LCT上的连通性问题! 于是被最后一个点卡了,似乎因为 find 函数只能找出连通性而 ...
- python datatime日期和时间值模块
datetime.time():是一个时间类,这个类接受4个参数,分别代表时,分,秒,毫秒.参数的默认值是为0 #!/usr/bin/env python #coding:utf8 import da ...
- python中socket编程
一.网络协议 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构(互联网中处处是C/S架构):B/S架构也是C/S架构的一种,B/S是浏览器/服务器 C/S架构与socket的关系: ...
- EntityFramework:An error occurred while executing the command definition. See the inner exception for details.
错误描述: 调用EF中的FirstOrDefault()时,报错误:An error occurred while executing the command definition. See the ...