Windows/Linux下C/C++内存泄露检测工具

50 篇文章 3 订阅
24 篇文章 0 订阅
本文介绍如何使用VisualLeakDetector和Valgrind检测Windows和Linux下的内存泄露问题。VisualLeakDetector适用于VC++环境,通过简单集成即可在程序退出时报告内存泄露情况。Valgrind则可在Linux环境下检测内存错误,并详细报告未释放的内存块。
摘要由CSDN通过智能技术生成

转自:http://blog.csdn.net/whisperlin/article/details/4446052

一 Window下的内存泄露检测(以VC++环境为例)

灵活自由是C语言的一大特色,但这个特色也难以避免的带来一些副作用,比如内存泄露。众所周知,内存泄露的问题比较复杂,程序正常运行时你看不出它有任何异常,但长时间运行或在特定条件下特定操作重复多次时,它才暴露出来。所以,内存泄露往往是难以发现,也难以定位解决的。

Visual Leak Detector(VLD)是一款用于Visual C++的免费的内存泄露检测工具,用户可从http://www.codeproject.com/tools/visualleakdetector.asp下载,该软件以库形式与用户的被测工程一起使用,由于VLD是按LGPL(GNU LESSER GENERAL PUBLIC LICENSE)协议对外开源,所以使用VLD是安全的,不必担心版权问题。

使用VLD

先从网站下载VLD的zip包,当前最高版本是V1.0,解压后得到vld.h、vldapi.h、vld.lib、vldmt.lib、vldmtdll.lib、dbghelp.dll等文件,把这些所有.h头文件拷贝到VC默认的include目录下,将所有.lib文件拷贝到VC默认的lib目录下,安装工作就完成了。

使用VLD很简单,只须在包含入口函数的CPP或C文件中把vld.h头文件包含进来即可。该include语句要求放在最前面,如果当前工程定义预编译head文件(如stdafx.h),则放在“#include <stdafx.h>”语句之后就可以了。之后正常编译、按Debug方式运行被测程序,等程序运行结束时,查阅VC的output窗口,会有“Visual Leak Detector is now exiting.”一句打印信息,在这条件信息之前,如果当前程序没有内存泄露会有“No memory leaks detected.”信息打印,但如果有内存泄露,将有类似如下信息打印:

    C:/VcTester21/sample/vc6/SampleMain.c (80): main

    crt0.c (206): mainCRTStartup

    0x7C816FD7 (File and line number not available): RegisterWaitForInputIdle

  Data:

      CD CD CD CD    CD                    ........ ........

   

Visual Leak Detector detected 1 memory leak.

这个信息指明当前发生内存泄露所在的函数及源文件行号,泄露内存块的地址、长度及当前内存值。用鼠标双击指示源码行的提示信息,VC即自动跳转到相应代码行,我们就很方便的知道是哪一行出错了。

可以看出,VLD用起来很简单,对它的实现原理感兴趣的朋友可以阅读VLD源码,也可参考dofty的文章:使用Visual Leak Detector检测内存泄露

二 Linux下的内存泄露检测(valgrind)

Valgrind 是在linux系统下开发应用程序时用于调试内存问题的工具。它尤其擅长发现内存管理的问题,它可以检查程序运行时的内存泄漏问题。

以上内容收集自Internet

 

 

   它的官方网址是 http://www.valgrind.org/

   下载最新版本的Valgrind,目前是3.2.0。 wget http://www.valgrind.org/downloads/valkyrie-1.2.0.tar.bz2

   按照里面的README提示,采用标准gnu软件安装方式,./configure — make —- makeinstall,安装后,输入valgrind ls -l 验证一下该工具是否工作正常(这是README里面的方法,实际上是验证一下对ls -l命令的内存检测),如果你看到一堆的信息说明你的工具可以使用了。

初次使用

编译如下代码: gcc -Wall example.c -g -o example

 

#include <stdlib.h>void f(void){ int* x = malloc(10 * sizeof(int)); x[10] = 0; // problem 1: heap block overrun} // problem 2: memory leak -- x not freedint main(void){ f(); return 0;}

     注意:gcc 的-g 选项让Valgrind调试输出时指出相应信息的代码所在的行号。

valgrind --tool=memcheck --leak-check=yes ./example

==6742== Memcheck, a memory error detector for x86-linux.

 

==6742== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.

==6742== Using valgrind-2.2.0, a program supervision framework for x86-linux.

==6742== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.

==6742== For more details, rerun with: -v

==6742==

==6742== Invalid write of size 4

==6742==    at 0x8048384: f (example.c:6)

==6742==    by 0x80483AC: main (example.c:12)

==6742== Address 0x1B908050 is 0 bytes after a block of size 40 alloc'd

==6742==    at 0x1B904984: malloc (vg_replace_malloc.c:131)

==6742==    by 0x8048377: f (example.c:5)

==6742==    by 0x80483AC: main (example.c:12)

==6742==

==6742== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 12 from 1)

==6742== malloc/free: in use at exit: 40 bytes in 1 blocks.

==6742== malloc/free: 1 allocs, 0 frees, 40 bytes allocated.

==6742== For counts of detected errors, rerun with: -v

==6742== searching for pointers to 1 not-freed blocks.

==6742== checked 1360800 bytes.

==6742==

==6742==

==6742== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1

==6742==    at 0x1B904984: malloc (vg_replace_malloc.c:131)

==6742==    by 0x8048377: f (example.c:5)

==6742==    by 0x80483AC: main (example.c:12)

==6742==

==6742== LEAK SUMMARY:

==6742==    definitely lost: 40 bytes in 1 blocks.

==6742==    possibly lost:   0 bytes in 0 blocks.

==6742==    still reachable: 0 bytes in 0 blocks.

==6742==         suppressed: 0 bytes in 0 blocks.

==6742== Reachable blocks (those to which a pointer was found) are not shown.

==6742== To see them, rerun with: --show-reachable=yes

   上面的C程序存在两个错误:1. 数组下标越界;2. 分配的内存没有释放,存在内存泄露的问题。对于错误1,看Valgrind的调试信息片断

==6742== Invalid write of size 4

 

==6742==    at 0x8048384: f (example.c:6)

==6742==    by 0x80483AC: main (example.c:12)

==6742== Address 0x1B908050 is 0 bytes after a block of size 40 alloc'd

==6742==    at 0x1B904984: malloc (vg_replace_malloc.c:131)

==6742==    by 0x8048377: f (example.c:5)

对于错误2,看这个

 

==6742== malloc/free: 1 allocs, 0 frees, 40 bytes allocated.

......

==6742== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1

==6742==    at 0x1B904984: malloc (vg_replace_malloc.c:131)

==6742==    by 0x8048377: f (example.c:5)

==6742==    by 0x80483AC: main (example.c:12)

Visual Leak Detector是一款免费的、健全的、开源的Visual C++内存泄露检测系统。相比Visual C++自带的内存检测机制,Visual Leak Detector可以显示导致内存泄露的完整内存分配调用堆栈。 下载Visual Leak Detector,当前版本2.2.3,在Visual C++ IDE的"工具"→"选项"→"项目和解决方案"→"VC++ 目录","包含文件"增加VLD的"\include"路径,"库文件"增加VLD的"\lib\Win32"路径,另外动态库"\bin\Win32"路径在安装时已经添加到环境变量里面了,若是未添加,则需要手动拷贝"\bin\Win32"下的文件到工程Debug目录。下 展开查看详细 收起信息 返回顶部 1.新建一个Win32控制台项目; 2.添加代码如下所示: #include "stdafx.h" #include "vld.h" int _tmain(int argc, _TCHAR* argv[]) { char *pBuf = new char[200]; return 0; } 3.在Debug模式下的“输出”窗口,将有如下信息: 报告列出了内存泄露是在第几块,所在的地址,泄露的字节,调用的堆栈,内存内容。双击调用堆栈可以跳转到所在行。 4.在Release模式下,不会链接Visual Leak Detector。 5.Visual Leak Detector有一些配置项,可以设置内存泄露报告的保存地(文件、调试器),拷贝"\Visual Leak Detector"路径下的vld.ini文件到工程的Debug目录下(在IDE运行的话,则需要拷贝到工程目录下),修改以下项: ReportFile = .\memory_leak_report.txt ReportTo = both 直接双击Debug目录下exe,文件内容跟“输出”窗口的内容一样。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值