background image

如何在 c++环境下检测内存泄露

首先,我们检查了代码,发现所有的代码都是用 new 来分配内存,用 delete 来释放内存。

 

那么,我们能够用一个全程替 换,来替换掉所有的 new 和 delete 操作符吗?不能。因为代
码的规模太大了,那样做除了浪费时间没有别的任何好处。好在我们的源代码是用 C++来

 

写成 的,所以,这意味着没有必要替换掉所有的 new 和 delete,而只用重载这两个操作符。

 

对了,值用重载这两个操作符,我们就能在分配和释放内存之前做点 什么。这是一个绝
对的好消息。我们也知道该如何去做。因为,MFC 也是这么做的。我们需要做的是:跟踪

 

所有的内存分配和交互引用以及内存释放。我们的源代 码使用 Visual C++写成,当然这种
解决方法也可以很轻松的使用在别的 C++代码里面。要做的第一件事情是重载 new 和
delete

 

操作符,它们将 会在所有的代码中被使用到。我们在 stdafx.h

 

中,加入:

 #ifdef _DEBUG 
 inline void * __cdecl operator new(unsigned int size,  
 const char *file, int line) 
 { 
 }; 

 inline void __cdecl operator delete(void *p) 
 { 
 }; 
 #endif 
   

这 样,我们就重载了 new 和 delete 操作符。我们用$ifdef 和#endif 来包住这两个重载操作

 

符,这样,这两个操作符就不会在发布版本中出现。看 一看这段代码,会发现, new 操
作符有三个参数,它们是,分配的内存大小,出现的文件名,和行号。这对于寻找内存泄

 

漏是必需的和重要的。否则,就会需要很 多时间去寻找它们出现的确切地方。加入了这段
代码,我们的调用 new()的代码仍然是指向只接受一个参数的 new 操作符,而不是这个接

 

受三个参数的操作 符。另外,我们也不想记录所有的 new 操作符的语句去包含__FILE__
和__LINE__参数。我们需要做的是自动的让所有的接受一个参数的 new

 

操 作符调用接受

三个参数的 new 操作符。这一点可以用一点点小的技巧去做,例如下面的这一段宏定义, 
 #ifdef _DEBUG 
 #define DEBUG_NEW new(__FILE__, __LINE__) 
 #else 
 #define DEBUG_NEW new 
 #endif 
 #define new DEBUG_NEW 
   

现 在我们所有的接受一个参数的 new 操作符都成为了接受三个参数的 new 操作符号,_

_FILE__和__LINE__

 

被预编译器自动的插入到其中了。然 后,就是作实际的跟踪了。我们

需要加入一些例程到我们的重载的函数中去,让它们能够完成分配内存和释放内存的工

 

 

作。这样来 做, #ifdef _DEBUG 
 inline void * __cdecl operator new(unsigned int size, 
 const char *file, int line) 
 { 
 void *ptr = (void *)malloc(size);