关闭

C++检查内存泄露

2763人阅读 评论(1) 收藏 举报

说明,我使用的ide是vs2008



1. 工程设置为debug

内存泄露的检测一般在debug模式下进行


2.在需要检查内存泄露的cpp头部加上

#ifdef	_DEBUG
 #define _CRTDBG_MAP_ALLOC
 #include <stdlib.h>
 #include <crtdbg.h>
 	#define new   new(_NORMAL_BLOCK, __FILE__, __LINE__)
 #endif

3.代码中插入这么一句话

EnableMemLeakCheck();

inline void EnableMemLeakCheck()
 {
 	_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
 }
 

4.然后就可以在输出中看泄露情况了

举个例子,例子中我用newEx表示的上述宏定义中的new

int _tmain(int argc, _TCHAR* argv[])
 {
 	EnableMemLeakCheck();
 	int num = 10;
 	byte **p = newEx byte *[num];
 	for (int i = 0; i < num; i ++)
 	{
 		Sleep(1);
 		*p = newEx byte[i];
 	}
 
 	long *pl = newEx long[100];
 
 	while(1)
 	{
 		Sleep(100);
 	}
 	return 0;
 }

输出中显示的内容(debug下运行程序,然后点叉叉关闭程序)

memory leaks!
 Dumping objects ->
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(101) : {124} normal block at 0x00295CB8, 400 bytes long.
  Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {122} normal block at 0x00294C30, 9 bytes long.
  Data: <         > CD CD CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {121} normal block at 0x00294BE8, 8 bytes long.
  Data: <        > CD CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {120} normal block at 0x00299F88, 7 bytes long.
  Data: <       > CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {119} normal block at 0x00299F40, 6 bytes long.
  Data: <      > CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {118} normal block at 0x00299EF8, 5 bytes long.
  Data: <     > CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {117} normal block at 0x00299EB8, 4 bytes long.
  Data: <    > CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {116} normal block at 0x00299E78, 3 bytes long.
  Data: <   > CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {115} normal block at 0x00299E38, 2 bytes long.
  Data: <  > CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {114} normal block at 0x00299DF8, 1 bytes long.
  Data: < > CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : {113} normal block at 0x00299DB8, 0 bytes long.
  Data: <> 励p
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(88) : {112} normal block at 0x00299D50, 40 bytes long.
  Data: <0L)             > 30 4C 29 00 CD CD CD CD CD CD CD CD CD CD CD CD 
 Object dump complete.


有文件名和行号,先申请的后释放。


扩展:

实际上是使用了另外的new,在dbgnew.cpp中,列一个例子说明:


void *__CRTDECL operator new[](
         size_t cb,
         int nBlockUse,
         const char * szFileName,
         int nLine
         )
         _THROW1(_STD bad_alloc)
 {
     void *res = operator new(cb, nBlockUse, szFileName, nLine );
 
     RTCCALLBACK(_RTC_Allocate_hook, (res, cb, 0));
 
     return res;
 }
 


注意,const char *szFileName可以使用__file__也可以使用自定义的类,经过重载为char*(感谢老马提供代码)

例如:

char new_index_recorder_file_name[1024 * 1024][256];
 
 
 
 class new_index_recorder{
 
 public:
 
 	new_index_recorder(char* file, int line) : file(file), line(line){
 
 
 
 	} 
 
 	operator char*(){
 
 		static unsigned int index;
 
 		sprintf(new_index_recorder_file_name[index], "%s(%d) : %d ", file, line, index++);
 
 		return  new_index_recorder_file_name[index];
 
 	}
 
 private:
 
 	char* file;
 
 	int line; 
 
 };


当然,也可以用函数来返回char*指针

int g_count = 0;
 
 class OperNew
 {
 public:
 	OperNew()
 	{	
 		g_count ++;
 		pC = new char[20];
 		memset(pC, 0, 10);
 		sprintf(pC, "No.%d", g_count);
 	}
 	char* GetChar()
 	{
 		return pC;
 	}
 private:
 	char * pC ;
 };

这样就能返回自定义的内容了。本次的返回加上了一个构造时候的序号,当然也可以添加时间等。结果如下:

e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(95) : 11 (95) : {123} normal block at 0x002B4C78, 400 bytes long.
  Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 10 (92) : {122} normal block at 0x002B4C30, 9 bytes long.
  Data: <         > CD CD CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 9 (92) : {121} normal block at 0x002B4BE8, 8 bytes long.
  Data: <        > CD CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 8 (92) : {120} normal block at 0x002B9F88, 7 bytes long.
  Data: <       > CD CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 7 (92) : {119} normal block at 0x002B9F40, 6 bytes long.
  Data: <      > CD CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 6 (92) : {118} normal block at 0x002B9EF8, 5 bytes long.
  Data: <     > CD CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 5 (92) : {117} normal block at 0x002B9EB8, 4 bytes long.
  Data: <    > CD CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 4 (92) : {116} normal block at 0x002B9E78, 3 bytes long.
  Data: <   > CD CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 3 (92) : {115} normal block at 0x002B9E38, 2 bytes long.
  Data: <  > CD CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 2 (92) : {114} normal block at 0x002B9DF8, 1 bytes long.
  Data: < > CD 
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(92) : 1 (92) : {113} normal block at 0x002B9DB8, 0 bytes long.
  Data: <> h鴌
 e:\project\test\test_mem_leak\test_mem_leak\test_mem_leak.cpp(88) : 0 (88) : {112} normal block at 0x002B9D50, 40 bytes long.
  Data: <0L+             > 30 4C 2B 00 CD CD CD CD CD CD CD CD CD CD CD CD 
 Object dump complete.
 程序“[8796] test_MEM_LEAK.exe: 本机”已退出,返回值为 -1073741510 (0xc000013a)。


小提示:

将输出文件拷贝到UE中,然后查找泄露行号出现的次数,可以计算出泄露的数目。



3
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Linux下几款C++程序中的内存泄露检查工具

Linux下编写C或者C++程序,有很多工具,但是主要编译器仍然是gcc和g++。最近用到STL中的List编程,为了检测写的代码是否会发现内存泄漏,了解了一下相关的知识。所有使用动态内存分配(dyn...
  • gatieme
  • gatieme
  • 2016-07-19 21:56
  • 11380

检查c#代码内存泄露工具-CLR Profiler

转自: http://blog.csdn.net/hualusiyu/article/details/8166450
  • wren2004
  • wren2004
  • 2014-07-31 20:33
  • 17792

linux C内存泄露检测实现及内存泄露检测的一般方法

学习,以后对vxworks和linux搞一套通用的,这样同事就方便了! linux中,由于使用malloc或alloc而没有free掉申请的内存,就会造成内存的泄露。通常,来讲为了避免内存泄露...
  • zyboy2000
  • zyboy2000
  • 2016-03-26 14:46
  • 2247

C和C++使用Lu键树实现智能指针及检查内存泄露

  • 2014-01-05 16:22
  • 185KB
  • 下载

用UMDH检查C++程序内存泄露

编写一个MFC测试程序CheckMemoryLeak来做实验,在该测试程序中分别加入两个按钮,用于申请内存,但不释放,为了在没有VS环境下检查内存泄露,可以使用UMDH工具,该工具在Windbg同一个...
  • chinabinlang
  • chinabinlang
  • 2014-04-29 16:28
  • 848

C/C++使用Lu键树实现智能指针及检查内存泄露

欢迎访问 Lu程序设计 C/C++使用Lu键树实现智能指针及检查内存泄露 1 说明     要演示本文的例子,你必须下载Lu32脚本系统。本文的例子需要lu32.dll、lu32.lib、C++格式...
  • forcal
  • forcal
  • 2014-01-03 11:58
  • 1925

内存泄露检查之C++实现

从事C++研发的筒子们,最挥之不去可能要数内存泄露带来的痛苦吧,在C++中,虽说其实现底层代码方面所凸显出来的性能要远高于其他类型语言,但是其由于缺乏天生的内存回收机制,从而也被业界予以诟病,那有没有...
  • zmyer
  • zmyer
  • 2014-03-18 20:29
  • 1262

Linux下几款C++程序中的内存泄露检查工具

本文更新记录 作者gatieme, CSDN. GitHub 2016-08-08 11:37, 添加了Linux内核内存检测工具Kmemleak 2016-08-08 11:43, 添加...
  • u012662731
  • u012662731
  • 2017-11-28 10:52
  • 110

C++内存泄露检查的5个方法

一、前言 在Linux平台上有valgrind可以非常方便的帮助我们定位内存泄漏,因为Linux在开发领域的使用场景大多是跑服务器,再加上它的开源属性,相对而言,处理问题容易形成“统一”的标准。...
  • fuck51cto
  • fuck51cto
  • 2016-12-08 23:34
  • 171

C++内存泄露,查询检查机制

C++程序的复杂性很大一部分在于他的内存管理,没有C#那样的垃圾回收机制,内存管理对初学者来说很困难。经常会出现内存泄露的情况。那么我们写程序如何避免内存泄露呢?首先我们需要知道程序有没有内存泄露,然...
  • ganpengjin1
  • ganpengjin1
  • 2014-02-28 22:30
  • 843
    个人资料
    • 访问:184125次
    • 积分:3407
    • 等级:
    • 排名:第11378名
    • 原创:103篇
    • 转载:50篇
    • 译文:12篇
    • 评论:37条
    博客专栏
    文章分类
    站长统计