C++ operator new[]和Debug Heap
原贴地址:
http://eparg.spaces.live.com/blog/cns!59BFC22C0E7E1A76!1490.entry
原贴时间:
2006-08-15
原贴作者:
eparg
如果在VS2005下面想用CRT Debug Heap来调试Memory Leak,最后可以用_CrtDumpMemoryLeaks 把所有的leak打印出来。尝试下面的代码,会怎样:
#include "stdafx.h"
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include<stdlib.h>
#include<crtdbg.h>
#endif
#define MY_NEW[s] new(s,_NORMAL_BLOCK, __FILE__, __LINE__)
#if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)
#define new MY_NEW
#endif
int _tmain(int argc, _TCHAR* argv[])
{
char *p=new char[10];
void *p2=malloc(10);
#ifdef _DEBUG
_CrtDumpMemoryLeaks();
#endif
return 0;
}
运行后会看到:
Detected memory leaks!
Dumping objects ->
c:\documents and settings\lixiong\my documents\mycode\detectleak\detectleak\detectleak.cpp(17) : {87} normal block at 0x003A8130, 10 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD
c:\program files\microsoft visual studio 8\vc\include\crtdbg.h(1150) : {86} normal block at 0x003A3240, 10 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD
Object dump complete.
The program '[808] DetectLeak.exe: Native' has exited with code 0 (0x0).
注意这里打印出的第一个leak,出现在detectleak.cpp的17行,对应的是malloc语句,没问题
可是第二个leak,出现在crtdbg.h的1150行,而不是new char[10]那里,怎么回事?如果不能定位到正确的源代码,还有什么用呢?
为了搞清楚这个问题,可以看看malloc在debug heap下的的定义:
#ifdef _CRTDBG_MAP_ALLOC
#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
注意看,这里用了__FILE__, __LINE__两个预处理器Directive:
The #line Directive
http://msdn2.microsoft.com/en-us/library/b5w2czay.aspx
由于与处理器自动把文件名和行号传递给了_malloc_dbg函数,最后的output窗口才可以打印出源代码行
那好,看看debug heap的new的定义。由于new是C++的关键字,而且是一个操作符,所以debug heap下定义为:
inline __bcount(_Size) void* __CRTDECL operator new[](size_t _Size)
{ return ::operator new[](_Size, _NORMAL_BLOCK, __FILE__, __LINE__); }
注意这里没有用#define,而是inline。同时该定义是在crtdbg.h文件中的。所以最后得到的是文件名是crtdbg.h。你可能有如下疑问:
1. 为什么不用#define而要用inline呢,改成#define可以吗?
你试试看吧,看能不能该成#define。由于这里有一个中括号,麻烦来了吧。谁让你是C++呢?bs一下C++
2. 为什么预处理器看到inline函数,不把inline后的行号和文件名字作为解释呢?
这我就不确定了啦。不过根据C++标准,标示为inline函数不是一定就要inline的,人家标准就定义得模棱两可,你何必强求预处理器呢?
所以,解决方法就是,所有的内存分配,就用:
#ifdef _CRTDBG_MAP_ALLOC
char *test=(char*)::operator new[](20, _NORMAL_BLOCK, __FILE__, __LINE__);
#else
char *test=new char[20];
#endif
你有其它好方法吗?
分享到:
相关推荐
new操作符(new operator)和operator new的区别,会很有帮助
C++_new_operator详解 C++_new_operator详解 C++_new_operator详解
c++ operator重载说明操作文档。
关于C++操作符重载的一个文档。有了它,关于操作符重载的东西你就不用再找资料拉~
创建c++的类文件,面向对象编程,提供编程实例
new operator/delete operator就是new和delete操作符,而operator new/operator delete是函数。 new operator(1)调用operator new分配足够的空间,并调用相关对象的构造函数(2)不可以被重载 operator new(1)只...
下面小编就为大家带来一篇C++ operator关键字(重载操作符)的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
乍一看,在C++中动态分配内存很简单:new是分配,delete是释放,就这么简单。然而,这篇文章讲得要复杂一点,并且要考虑到自定义层次。这也许对简单的程序并不重要,但对你在代码中控制内存却是十分必要的,是否能写...
C++ operator两种用法.docx
软件设计课件:Lecture 07 C++ Operator Overloading.ppt
简述 C++ 中的 new 和 delete 的基本原理,并讲述了内存检测子系统的实现原理、实现中的技巧,并对内存泄漏检测的高级话题进行了讨论。解决了本人在内存泄露很多多问题(我也是down的别人的),觉得非常好,所以给...
C++中使用new运算符产生一个存在于Heap(堆)上对象时,实际上调用了operator new()函数和placement new()函数。在使用new创建堆对象时,我们要清楚认清楚new的三种面貌,分别是:new operator、operator new()和...
拨开自定义operator new与operator delete的迷雾
c++中operator的用法.docx
在c++中,如果没有定义operator=操作,编译器会提供一个默认的operator=操作。由于operator=操作和拷贝构造函数的功能类似,都执行拷贝操作。因此,编译器也分提供无用的默认operator=操作和非无用的默认operator=...
operator=赋值自我检测,小程序,给自己参考学习
C++ 支持使用 new 和 delete 运算符动态分配和释放对象。这些运算符为来自称为“自由存储”的池中的对象分配内存。 new 运算符调用特殊函数 operator new,delete 运算符调用特殊函数 operator delete。 在 Visual ...
C++中内存的动态分配与管理永远是一个让C++开发者头痛的问题,本文通过对C++中内存的动态分配释放的基本原理的介绍,让读者朋友能对C++中的内存的动态分配与释放有较为... 上面是C++中operator new function的原型