|
|
如同大多数书所介绍的一般,内存是片雷区,容易发生错误。而内存泄露,作为BUG的一种,又往往难以觉察.在这里我提出一种简易的内存使用跟踪程序,供大家参考。偶这个东西值得优化的地方很多。同志们请自行研究。
基本原理是首先定义一个结构,里面包含了指针的首地址,源文件名以及new的时候的所在行。然后用一个连表来存储他。分配内存的时候,向连表压入一个接点,而释放内存的时候,则根据指针首地址来把接点从连表删除。为了实现这个目的,我们需要重载new operator和delete operator。那么,如果在程序结束的时候连表不空的话,显然就发生了内存泄露了:因为new/delete不配对嘛~ 我们就可以遍历连表,找出问题所在。
基本原理就是这样。以下是代码,我适当加了注释。
/*以下开始为内存泄露监视系统*/
//连表结构
typedef struct _NODE
{
void* ptr; //指针首地址
char fn[255]; //文件名
unsigned long line; //行号
public:
_NODE& operator = (const _NODE& r){ this->line=r.line;this->ptr=r.ptr;strcpy(this->fn,r.fn); return *this;} //重载付值
bool operator==(const _NODE& r){ return this->ptr==r.ptr;} //重载判断
}NODE,*PNODE,*LPNODE;
list<NODE> buffer; //内存使用情况链
#ifdef _DEBUG
//重载new operator 使能记录内存使用情况
void* operator new(size_t _size,char* _fn,unsigned long _line)
{
NODE node;
node.ptr=operator new(_size); //调用基本的new operator来分配内存而不用malloc,是考虑到可能会给CLASS分配内存,需要调用constructor.....省得placement new了
node.line=_line;
strcpy(node.fn,_fn);
buffer.push_back(node);
return node.ptr;
}
#endif
#ifdef _DEBUG
//DEBUG模式下的内存释放
void operator delete(void* _ptr)
{
//以下是典型的STL迭带器使用,没什么好说的
list<NODE>::iterator it=buffer.begin();
while(it!=buffer.end())
{
if(it->ptr==_ptr)
{
buffer.erase(it);
delete _ptr;
return;
}
++it;
}
}
#endif
//为了方便使用,引入NEW关键字的定义,该监视系统仅在DEBUG模式时有效。以后分配内存时就都用NEW了,而不用new
#ifdef _DEBUG
#define NEW new(__FILE__,__LINE__)
#else
#define NEW new
#endif
/*监视系统结束*/
本文是在复习高等代数考试无聊的时候写的~可能会有错误。请您支持。最后送上代码,代码我只测试了几次....如果发现错误,请指出。谢谢
|
|