内存泄漏也称作"存储渗漏",用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。(其实说白了就是该内存空间使用完毕之后未回收)即所谓内存泄漏。
在此写了一个检测C++程序内存泄漏的小程序,支持Windows和Linux
思想:开辟空间即使用new时将信息储存在链表中,delete时将对应的信息删除,若程序运行结束链表为空,则没有发生内存泄漏,反之则有内存泄漏,将对应信息打印出来。
上代码:
//LW_VLD.h
#pragma once
#include<assert.h>
#include<iostream>
using namespace std;
typedef struct MemNode
{
char *file;
size_t line;
size_t size;
struct MemNode *link;
}MemNode;
//stl list
typedef struct MemLeak
{
MemNode *head;
MemNode *tail;
}MemLeak;
static MemLeak mlist = {0,0};
///
void* operator new(size_t sz, const char *file, size_t line)
{
void *ptr = NULL;
MemNode *s = (MemNode*)malloc(sizeof(MemNode)+sz);
assert(s != NULL);
s->file = (char*)file;
s->line = line;
s->size = sz;
s->link = NULL;
if(mlist.head == NULL)
{
mlist.head = mlist.tail = s;
}
else
{
mlist.tail->link = s;
mlist.tail = s;
}
ptr = s+1;
return ptr;
}
void operator delete(void *ptr)
{
MemNode *pre = NULL;
MemNode *p = mlist.head;
while(p != NULL)
{
if(p+1 == ptr)
{
if(p == mlist.head)
{
mlist.head = p->link;
}
else
{
pre->link = p->link;
if(pre->link == NULL)
mlist.tail = pre;
}
free(p);
break;
}
pre = p;
p = p->link;
}
}
void* operator new[](size_t sz, const char *file, size_t line)
{
return ::operator new(sz, file, line);
}
void operator delete[](void *ptr)
{
return ::operator delete(ptr);
}
void check_vld()
{
int index = 0;
MemNode *p = mlist.head;
if(p == NULL)
{
printf("===> vld check : No Memory Leak. <===\n");
return;
}
while(p != NULL)
{
index++;
printf("[%d]===>vld check: at %s, at %d line, %d bytes memleak<===\n",index,p->file,p->line,p->size);
p = p->link;
}
}
#define new new(__FILE__,__LINE__)
class LWVLD
{
public:
~LWVLD()
{
check_vld();
}
};
static LWVLD lwvld;
在main函数所在的文件引入#include“LW_VLD”即可使用
主函数:
#include<iostream>
#include"LW_VLD.h"
using namespace std;
class Test
{
public:
Test()
{
data = new int;
}
~Test()
{
}
private:
int *data;
};
class Test1
{
public:
Test1()
{
data = new int;
}
~Test1()
{
delete data;
data=NULL;
}
private:
int *data;
};
void main()
{
int *p=new int[7];
Test a;
Test1 b;
}
Test类中的析构函数没有delete,主函数里面的*P也没有释放空间,而Test1释放了,对比一下可以看到
主函数第36行有28个字节的内存泄漏,第10行有4个字节的内存泄漏,而析构函数delete过的Test1类定义的b对象并没有产生内存泄漏
该程序有很多改进的地方,比如代码过长大量开辟空间时候在链表中查找信息效率可能略低,如需提高效率可使用哈希表。还可写出在C下检测的程序,思想同上,将malloc和free重载即可。