C++内存泄露解析

1、定义

内存泄露简单的说就是申请了一块内存空间,使用完毕后没有释放掉。它的一般表现方式是程序运行时间越长,占用内存越多,最终用尽全部内存,整个系统崩溃。

2、内存泄露的各种情况

1)new,malloc后没有delete,free

2)创建内核对象(比如CreateFile,CreateMutex,CreateThread),后没有释放内核对象句柄.

3)创建内存映射文件,CreateFileMapping,MapViewOfFile后没有CloseHandle(),UnMapviewofFile

4)创建GDI对象后,比如LoadIcon,LoadImage,CreateImageList等等,没有Destroy掉

5)创建DC后,比如GetDC(), 没有释放DC句柄

6)保留虚拟地址空间 VirtualAlloc(),然后提交物理存储器后,没有释放掉


2、泄漏的分类
  以发生的方式来分类,内存泄漏可以分为4类:
(1). 常发性内存泄漏。
  发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。
(2). 偶发性内存泄漏。
  发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。
(3). 一次性内存泄漏。
  发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。
(4). 隐式内存泄漏。
  程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。


3、使用Purify(适用所有UNIX平台)工具对内存泄漏进行分析

1.使用Purify对内存泄漏进行分析

Purify是IBM Rational PurifyPlus的工具之一,是一个面向VC、VB或者Java开发的测试Visual C/C++和Java代码中与内存有关的错误的工具,它确保整个应用程序的质量和可靠性。在查找典型的C/C++程序中的传统内存访问错误,Rational Purify可以大显身手。在UNIX系统中,使用Purify需要重新编译程序。通常的做法是修改Makefile中的编译器变量。

例如定义CC变量为purify gcc

 
 
  1. CC=purify gcc  

首先运行Purify安装目录下的purifyplus_setup.sh来设置环境变量,然后运行make重新编译程序。需要指出的是,程序必须编译成调试版本。在编译器命令(例如Solaris的CC编译器,Linux的gcc编译器等)后,也就是必须使用"-g"选项。在重新编译的程序运行结束后,Purify会打印出一个分析报告。

测试程序(此代码使用C++语言实现):

 
 
  1. #include <stdlib.h>   
  2. void func1()   
  3. {   
  4.    //char* pBuf = new char;   
  5. }   
  6.  
  7. void func2()   
  8. {   
  9.    char* pBuf = new char;   
  10. }   
  11.  
  12. void func3()   
  13. {   
  14.    char* pBuf = new char;   
  15. }   
  16.  
  17. int main()   
  18. {   
  19.    func1();   
  20.    func2();   
  21.    func3();   
  22.    return 0;   
  23. }  

编译程序:

 
 
  1. [dyu@xilinuxbldsrv purify]$ purify g++ -g tst.cpp -o tst1  

Purify输出:

 
 
  1. [dyu@xilinuxbldsrv purify]$ ./tst1   
  2.  16:50:59 (rational) OUT: "PurifyPlusUNIX" dyu@xilinuxbldsrv    
  3.  ****  Purify instrumented ./tst1 (pid 530 at Fri Apr  6 16:50:59 2012)   
  4.   * Purify 7.0.0.0-014 090319 Linux (64-bit) (C) Copyright IBM Corporation. 1992,   
  5.   * 2009 All Rights Reserved.    
  6.   * For contact information type: "purify -help"  
  7.   * For Purify Viewer output, set the DISPLAY environment variable.   
  8.   * License successfully checked out.   
  9.   * Command-line: ./tst1   
  10.   * Options settings: -g++=yes -purify \   
  11. -purify-home=  
  12. /home/dyu/purify/PurifyPlus.7.0.0.0-014/Rational/releases/\  
  13. purify.i386_linux2.7.0.0.0-014  
  14. -process-large-objects=yes -gcc3_path=/usr/bin/g++ \   
  15. -cache-dir=  
  16. /home/dyu/purify/PurifyPlus.7.0.0.0-014/Rational/releases/\  
  17. purify.i386_linux2.7.0.0.0-014\  
  18. /cache  
  19.  
  20.  ****  Purify instrumented ./tst1 (pid 530)  ****   
  21.  Current file descriptors in use: 5   
  22.  FIU: file descriptor 0: <stdin>   
  23.  FIU: file descriptor 1: <stdout>   
  24.  FIU: file descriptor 2: <stderr>   
  25.  FIU: file descriptor 26: <reserved for Purify internal use>   
  26.  FIU: file descriptor 27: <reserved for Purify internal use>   
  27.  
  28.  ****  Purify instrumented ./tst1 (pid 530)  ****   
  29.  Purify: Searching for all memory leaks...   
  30.  
  31.  Memory leaked: 2 bytes (100%); potentially leaked: 0 bytes (0%)   
  32.  
  33.  MLK: 1 byte leaked at 0xa457098   
  34.   * This memory was allocated from:   
  35.         malloc         [rtlib.o]   
  36.         operator new(unsigned long) [libstdc++.so.6]   
  37.         operator new(unsigned long) [rtlib.o]   
  38.         func2()        [tst.cpp:9]   
  39.         main           [tst.cpp:20]   
  40.         __libc_start_main [libc.so.6]   
  41.         _start         [crt1.o]   
  42.  
  43.  MLK: 1 byte leaked at 0xa457138   
  44.   * This memory was allocated from:   
  45.         malloc         [rtlib.o]   
  46.         operator new(unsigned long) [libstdc++.so.6]   
  47.         operator new(unsigned long) [rtlib.o]   
  48.         func3()        [tst.cpp:14]   
  49.         main           [tst.cpp:21]   
  50.         __libc_start_main [libc.so.6]   
  51.         _start         [crt1.o]   
  52.  
  53.  Purify Heap Analysis (combining suppressed and unsuppressed blocks)   
  54.                          Blocks        Bytes   
  55.               Leaked          2            2   
  56.   Potentially Leaked          0            0   
  57.               In-Use          0            0   
  58.   ----------------------------------------   
  59.      Total Allocated          2            2  

Purify图形输出:

安装Xmanager等工具,设置DISPLAY为本机IP,见下图:

 
 
  1. [dyu@xilinuxbldsrv purify]$ export DISPLAY=9.119.131.33:0  

Figure xxx. Requires a heading

输出分析:

从purify的输出可以看出,此测试程序存在两处内存泄漏,它分别是func2和func3,在tst.cpp文件的第9和第14行。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值