VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 8268|回复: 116

[原创] Windows平台上C++开发内存泄漏检查方法

  [复制链接]
79_avatar_middle
在线会员 发表于 2015-12-20 20:58:36 | 显示全部楼层 |阅读模式
充分的利用调试工具可以非常方便地避免内存泄漏问题。


    这里介绍两种方法,互为补充,第一种是VC编译器提供的方法,第二种是专用的内存泄漏检查工具Memmory Validator。这两种方法的基本原理是一样的:内存分配要通过CRT在运行时实现,只要在分配内存和释放内存时分别做好记录,程序结束时对比分配内存和释放内存的记录就可以确定是不是有内存泄漏。其中,第一种方法重载了new操作符,第二种方法是替换了CRT运行时库,在用户程序与运行库之间加了一层,用于记录内存分配情况。两种方法的不同是前者是在编译时完成的,分析内存情况的代码编译到执行文件中,用于程序的debug版本,后一种对编译过程没有影响,在执行过程中截留与CRT的交互信息。

     第一种方法是MSDN中介绍了,在需要检查内存分配情况的cpp文件中引用<stdlib.h>和<ctrdbg.h>两个头文件,放于最头部,再用宏代换的方法用重载后的new操作符代替原来的new操作符,如下列代码所示,在程序退出的位置调用_CrtDumpMemoryLeaks()输出全部没有释放的内存内容,及申请这些内存的源代码位置,非常便于调试。

     但这种方法有缺陷,_CrtDumpMemoryLeaks()必须在main()函数结束之前调用,所以main()函数中的栈对象还没有析构,会被当做内存泄漏,如下面代码中的NewClass类的对象,实际是没有问题的。另外就是不同编译器实现非ASCII码字符时可能会有所不同,如下面代码中的汉字串都被视为内存泄漏。
#include <stdlib.h>
#include <crtdbg.h>

#include <string>
#include <iostream>
#include <vector>
using namespace std;

#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW

struct AlertDescriptionString
{
     unsigned int ID;
     string Name;
     string Desp;
};

const AlertDescriptionString String[] =
{
    {0,"AAA","BBBB"},
     // memory leak count by _CRTDBG_MAP_ALLOC
    {1,"CCC","__XXX__检测到可能由AirJack发出的数据包"}
};

struct AlertDescriptionStr
{
     unsigned int ID;
     char* Name;
      char* Desp;
};

const AlertDescriptionStr Str[] =
{
     {0,"AAA","BBBB"},
     {1,"CCC","检测到可能由AirJack发出的数据包"}
};

void leak_memory(void)
{
      vector<unsigned int *> vec;
      for( int j = 0; j < 2; j++)
     {
           vec.push_back(new unsigned int(0));
     }
}

class NewClass
{
      void * p ;
public:
NewClass()
{
      p = (void*) new char[10];
}
~NewClass()
{
      delete [] p;
}
};

int * p = new int(9);

int real_main_fun (int argc, char ** argv)
{
      leak_memory();
      return 0;
}

int main (int argc, char ** argv)
{

      string str("__YYY__检测到可能由AirJack发出的数据包");
      NewClass cls;

      int i = real_main_fun(argc, argv); // 原有的main函数体

      if(_CrtDumpMemoryLeaks())
      cout<< " memory leak " << endl;
      return i;
}

    第二种方法正好是它的补充,Memmory Validator可以检查程序整个运行过程中的内存分配情况,也可以将内存泄漏的位置显示出来,如图所示。
memory validato的界面
在实际应用第一种方法时,可以采用两个头文件,用于大型工程的调试,几乎不对其他部分代码产生影响。

-----------------------------------------------------------------------------
//config.h
#define MEMORY_DEBUG
#ifdef MEMORY_DEBUG
#include <stdlib.h>
#include <crtdbg.h>
#endif // MEMORY_DEBUG
------------------------------------------------------------------------------
//debug.h
#ifdef MEMORY_DEBUG
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif // MEMORY_DEBUG
-------------------------------------------------------------------------------
//main.cpp
#include "config.h” // config.h, 第一个头文件
#include "alertparser.h"
#include "alertinfocache.h"
#include <iostream>
#include <pcap.h>
#include "debug.h" //debug.h, 最后一个头文件

int main (int argc, char ** argv)
{

      int i = real_main_fun(argc, argv); // 原有的main函数体

      if(_CrtDumpMemoryLeaks())
      cout<< " memory leak " << endl;
      return i;
}

评分

参与人数 6驿站币 +8 热心值 +8 收起 理由
88_avatar_small 寂寞江湖 + 2 + 2 感谢分享!
16_avatar_small 阳光 + 1 + 1 感谢分享!
65_avatar_small 编程者 + 2 + 2 赞一个!
01_avatar_small 天下第一 + 1 + 1 感谢分享!
28_avatar_small 天下 + 1 + 1
10_avatar_small cmx006 + 1 + 1

查看全部评分





上一篇:如何在vc6.0中使用duilib库
下一篇:如果是初学C语言请看完 一些成功人士的心得
69_avatar_middle
在线会员 发表于 2015-12-20 21:01:39 | 显示全部楼层
看看是什么
47_avatar_middle
在线会员 发表于 2015-12-20 21:34:50 | 显示全部楼层
看看是啥!
53_avatar_middle
在线会员 发表于 2015-12-20 23:25:41 | 显示全部楼层
看看, 谢谢
23_avatar_middle
online_vip 发表于 2015-12-20 23:40:31 | 显示全部楼层
这个牛逼
72_avatar_middle
在线会员 发表于 2015-12-21 00:17:47 | 显示全部楼层
看看是什么情况
50_avatar_middle
在线会员 发表于 2015-12-21 01:47:24 | 显示全部楼层
简单 ...
08_avatar_middle
在线会员 发表于 2015-12-21 07:07:49 | 显示全部楼层
Windows平台上C++开发内存泄漏检查方法
10_avatar_middle
在线会员 发表于 2015-12-21 09:19:22 | 显示全部楼层
谢谢分享啊
06_avatar_middle
在线会员 发表于 2015-12-21 09:28:33 | 显示全部楼层
看看是什么
45_avatar_middle
在线会员 发表于 2015-12-21 11:03:55 | 显示全部楼层

看看是什么
28_avatar_middle
在线会员 发表于 2015-12-21 11:30:31 | 显示全部楼层
学习一下
82_avatar_middle
在线会员 发表于 2015-12-21 16:15:51 | 显示全部楼层
我抱着强烈的欲望来回复
15_avatar_middle
在线会员 发表于 2015-12-21 16:24:25 | 显示全部楼层
顶楼主啦..希望楼主多发精品好帖啦.....
44_avatar_middle
在线会员 发表于 2015-12-22 07:21:46 | 显示全部楼层
kankan.........
71_avatar_middle
在线会员 发表于 2015-12-22 09:07:49 | 显示全部楼层
看看是什么.....                                         
92_avatar_middle
online_vip 发表于 2015-12-22 09:46:37 | 显示全部楼层
查看一下
24_avatar_middle
在线会员 发表于 2015-12-22 11:11:11 | 显示全部楼层
来学习学习的
69_avatar_middle
在线会员 发表于 2015-12-22 11:12:16 | 显示全部楼层
内存 是永恒的话题啊
65_avatar_middle
在线会员 发表于 2015-12-22 14:00:56 | 显示全部楼层
Windows平台上C++开发内存泄漏检查方法Windows平台上C++开发内存泄漏检查方法
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2019-5-23 03:48

Powered by Discuz! X3.4

© 2009-2019 cctry.com

快速回复 返回顶部 返回列表