如何在 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);