C++堆内存检查

#include <cstdio>
#include <map>

#define MEM_NEW(T,n)			mem_alloc<T>(n, __TIME__, __FILE__, __LINE__);
#define MEM_DELETE(p)			if(p)\
					           {\
						           mem_free(p);\
					           };
#define MEM_CHECK()			mem_check();

struct AllocInfo
{
	const char*	time;
	const char*	file;
	int		       line;
};

std::map<void*,AllocInfo> g_UserMem;

/*
*使用模板函数为了new的时候明确类型从而调用构造函数 
*明确返回此类的对象指针不必类型转换
*/
template<typename T>
T* mem_alloc(int _size,
		const char* 	_time,
		const char* 	_file,
		const int	   _line)
{
	void* p = new T[_size];
	if(p)
	{
		AllocInfo _Info = {_time,_file,_line};
		g_UserMem.insert(make_pair(p,_Info));
		return static_cast<T*>(p);
	}
	else
	{		
		return NULL;
	}
}

/*
*使用模板函数为了delete时明确类型从而调用析构函数 
*找到key对应的内存地址返回迭代器清除容器成员
*/
template<typename T>
int mem_free(T* _point)
{
	map<void*,AllocInfo>::iterator it_map = g_UserMem.find(_point);
	if(it_map != g_UserMem.end())//未找到返回尾部元素后一个地址
	{
		delete[] _point;
		g_UserMem.erase(it_map);
		return 0;
	}
	else
	{
		return -1;
	}
}

void mem_check()
{
	printf("----------[Memory Check]----------\n");

	if(!g_UserMem.size())
	{
		printf("Memory have all been released\n");
		return;
	}

	printf("Exist memory hasn't be freed:\n");

	std::map<void*,AllocInfo>::iterator it_map = g_UserMem.begin();
	for(;it_map!=g_UserMem.end();++it_map)
	{
		if(it_map->first)
		{
			printf("Memory Allocation Time:[%s]\n\t%s - Line:%d\n",\
				it_map->second.time, it_map->second.file, it_map->second.line);
		}
	}
}

由于C++的模版不支持头文件和CPP文件分离 所以以上函数定义在头文件中

下面是测试代码

将平时的new和delete操作替换成宏函数即可,在程序退出前检查

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

class A
{
public:
	A()
	{
		cout<<"A"<<endl;
	}

	~A()
	{
		cout<<"~A"<<endl;
	}
};

int main()
{
	A *p = MEM_NEW(A,1);
	MEM_DELETE(p);
	p = NULL;
	
	int* pa=new int;
	MEM_DELETE(pa);//不是用自定义的方式申请的内存释放无效
	delete pa;
	pa = NULL;
	
	MEM_CHECK();

	getchar();
	return 0;
}


转载于:https://my.oschina.net/mlgb/blog/262943

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值