C++ operator new[]和Debug Heap

原创 2007年09月19日 21:34:00

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.cpp17行,对应的是malloc语句,没问题

可是第二个leak,出现在crtdbg.h1150行,而不是new char[10]那里,怎么回事?如果不能定位到正确的源代码,还有什么用呢?

为了搞清楚这个问题,可以看看mallocdebug 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 heapnew的定义。由于newC++的关键字,而且是一个操作符,所以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

你有其它好方法吗?

 

C++ 出现异常“.... \debug_heap.cpp Line:980 Expression:__acrt_first_block==header"

我的运行环境为VS2015+Opencv2.4.11  FindContours函数出现的调用异常问题如下:    错误:File: minkernel\crts\ucrt\src\appcrt\he...

c++: Does the new operator for dynamic allocation check for memory safety?

Quesion: My question arises from one of my c++ exercises (from Programming Abstraction in C++, 2012...

operator new在C++中的各种写法

转自:http://article.yeeyan.org/view/215147/182456 简介 你知道operator new和new operator的区别吗?你听说过pl...
  • yasi_xi
  • yasi_xi
  • 2013年01月09日 19:58
  • 698

C++ 工程实践(2):不要重载全局 ::operator new()

对于现实生活中的 C++ 项目,重载 ::operator new() 几乎没有用武之地,因为很难处理好与程序所用的 C++ library 的关系。如果确实需要,我们可以从 malloc 层面入手,...
  • Solstice
  • Solstice
  • 2011年02月22日 01:23
  • 16212

学习c/c++之operator new(仅供参考)

operator new   function void* operator new (std::size_t size) throw (std::bad_alloc); void* oper...

operator new在C++中的各种写法

 乍一看,在C++中动态分配内存很简单:new是分配,delete是释放,就这么简单。然而,这篇文章讲得要复杂一点,并且要考虑到自定义层次。这也许对简单的程序并不重要,但对你在代码中控制内存却是...

C++ 工程实践(2):不要重载全局 ::operator new()

陈硕 http://blog.csdn.net/solstice/article/details/6198937   C++ 工程实践(2):不要重载全局 ::operator new...

C++笔记(常用关键字new、delete、static、const、friend,operator+-,内存结构)

1.new ,delete //C++ 通过new(delete)动态内存分配 //而C则是通过 malloc(free) Son* s1 = new Son(12); ...
  • ccj659
  • ccj659
  • 2016年09月05日 09:44
  • 257

实战c++中的智能指针unique_ptr系列-- 使用std::unique_ptr代替new operator(错误:‘unique_ptr’ is not a member of ‘std’)

写了很多篇关于vector的博客,其实vector很便捷,也很简单。但是很多易错的问题都是vector中的元素为智能指针所引起的。所以决定开始写一写关于智能指针的故事,尤其是unique_ptr指针的...

C++ Placement Operator New

placement new是重载operator new的一个标准、全局的版本,它不能被自定义的版本代替(不像普通的operator new和operator delete能够被替换成用户自定义的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ operator new[]和Debug Heap
举报原因:
原因补充:

(最多只允许输入30个字)