码迷,mamicode.com
首页 > 其他好文 > 详细

自己实现简易的内存泄露检测工具VLD

时间:2015-08-30 23:16:25      阅读:238      评论:0      收藏:0      [点我收藏+]

标签:内存泄露   检测   cc++   vld   

有一个很著名的内存泄露检测工具Visual leak detected想必大家都不陌生,但今天我们可以自己写一个简易版的。哈哈,自己动手,丰衣足食有木有!!!

它的原理就是我们重载了操作符new和delete,当用new开辟空间的时候,就讲这块空间串到我们定义的结构体MEMNode形成的链表中,(这是老师的写法,在main程序结束时,用check_vld()函数检测有没有内存泄露)但我觉得,如果我们动态开辟了一个对象,在它的析构函数里用delete释放的话,这种方法就不太可行。因为析构函数只有到return时才会被调用(在check_vld()函数之前)。检测结果就不准确。由此我想到,可以将这个结构体该为C++中的类class MEMNode,并将其指针也封装为一个类PMEMNode,然后定义一个PMEMNode的全局静态成员(它会在主函数之前被构造,主函数结束后析构)。并将check_vld()的代码放在他的析构函数中。

废话不多说,代码在下面:

vld.h:

#pragma once

#include <iostream>
using namespace std;

class MemNode {
	friend void* operator new(size_t sz, char *filename, int line);
public:
	MemNode(int s = 0,char *pf = NULL, int l = 0,class MemNode *pl=NULL)
		:size(s),file(pf),line(l),link(pl)
	{}
	~MemNode()
	{}
	void set(int sz, char *pf, int l, class MemNode *pl)
	{
		size = sz;
		file = pf;
		line = l;
		link = pl;
	}
	void setlink(MemNode *pl)
	{
		link = pl;
	}
	int getsize()
	{
		return size;
	}
	char *getfile()
	{
		return file;
	}
	int getline()
	{
		return line;
	}
	MemNode *getlink()
	{
		return link;
	}
private:
	int size;
	char *file;
	int line;
	class MemNode *link;
};

void check_vld();

class pMemNode {
public:
	pMemNode(MemNode *ptr=NULL):p(ptr){}
	~pMemNode()
	{
		check_vld();
	}
	MemNode *getptr()
	{
		return p;
	}
	void setptr(MemNode *ptr)
	{
		p = ptr;
	}
private:
	MemNode *p;
};

static pMemNode _AfxMem;

void* operator new(size_t sz,char *filename,int line)
{
	void *result=NULL;
	int total_size = sz + sizeof(MemNode);
	MemNode *p = new MemNode[total_size];
	p->set(sz, filename, line, NULL);
	if (_AfxMem.getptr() == NULL)
	{
		_AfxMem.setptr(p);
	}
	else
	{
		p->setlink(_AfxMem.getptr());
		_AfxMem.setptr(p);
	}
	result = _AfxMem.getptr()+1;
	return result;
}

void operator delete(void *ptr)
{
	if(_AfxMem.getptr()==NULL)
	{
		return;
	}
	if(ptr==NULL)
	{
		return;
	}
	MemNode *p;
	if (_AfxMem.getptr()+1 == ptr)
	{
		p = _AfxMem.getptr();
		_AfxMem.setptr(p->getlink());
		delete p;
	}
	else
	{
		p = _AfxMem.getptr();
		while (p->getlink() != NULL && p->getlink()+1!=ptr)
		{
			p = p->getlink();
		}
		if (p->getlink() != NULL)
		{
			MemNode *q = p->getlink();
			p->setlink(q->getlink());
			delete q;
		}
	}
}

void check_vld()
{
	if (_AfxMem.getptr() == NULL)
	{
		cout << "No memory Leaks detected." << endl;
	}
	else
	{
		MemNode *p = _AfxMem.getptr();
		cout << "WARNING: Visual Leak Detector detected memory leaks!" << endl;
		while (p != NULL)
		{
			printf("At %p: %d Bytes\n", p + 1, p->getsize());
			printf("file: %s, line: %d\n", p->getfile(), p->getline());
			p = p->getlink();
		}
	}
}

Main.cpp:

#include <iostream>
#include <string>
#include "vld.h"
using namespace std;

class Test
{
public:
	Test(char *str)
	{
		int a = strlen(str) + 1;
		ch = new(__FILE__, __LINE__) char[a];
		//strcpy(ch, str);
	}
	~Test()
	{
		delete[]ch;
		ch = NULL;
	}
private:
	char *ch;
	int a;
	double b;
	char c;
};

int main()
{
	//VLD vld;
	int a = 10;
	Test t("hello");
	//int *p = new(__FILE__,__LINE__) int(10);
	//double *q = new(__FILE__,__LINE__) double(12.34);
	Test *s = new(__FILE__,__LINE__) Test("hello");

	//delete p;
	//delete q;
	//check_vld();
	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

自己实现简易的内存泄露检测工具VLD

标签:内存泄露   检测   cc++   vld   

原文地址:http://blog.csdn.net/smartbrave/article/details/48109509

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!