在我们使用内存的时候,偶尔会由于疏忽而忘记释放掉已用完的内存,从而引起内存泄露,因此可以写一个内存管理的程序,用来检查那些内存泄露,在什么位置,从而能使程序更高效。

代码如下:

#pragma once              //头文件
#include <iostream>
using namespace std;
#include <string>
#include <list>
#include <assert.h>
struct BlockInfo
{
 void* _ptr;
 string _file;
 int _line;
 BlockInfo(void* ptr, const char* file, int line)
  :_ptr(ptr)
  ,_file(file)
  ,_line(line)
 {}
};

void* Alloc(size_t size, const char* file, int line);
void Dealloc(void* ptr);
void Print();

template<class T>
T* __NEW(size_t size,const char* file,int line)
{
 T* ptr = (T*)Alloc(size,file,line);
 return new(ptr) T;
}
template<class T>
void __DELETE(T* ptr)
{
 ptr->~T();
 Dealloc(ptr);
}
#define NEW(type)  __NEW<type>(sizeof(type),__FILE__,__LINE__)
#define DELETE(ptr)  __DELETE(ptr)
#define NEW_ARRAY(type,num)  __NEW_ARRAY<type>(sizeof(type)*num+4,__FILE__,__LINE__)
#define DELETE_ARRAY(ptr)  __DELETE_ARRAY(ptr);
template<class T>
T* __NEW_ARRAY(size_t size,const char* file,int line)
{
 T* ptr = (T*)Alloc(size,file,line);
 int num = (size-4)/sizeof(T);
 *((int*)ptr) = num;
 int i = 0;
 T* tmp = (T*)(((int*)ptr)+1);
 while(i < num)
 {
  new(tmp) T;
  ++i;
  ++tmp;
 }
 return (T*)(((int*)ptr)+1);
}
template<class T>
void __DELETE_ARRAY(T* ptr)
{
 int num = *(((int*)ptr)-1);
 T* tmp = (T*)ptr;
 while(num)
 {
  tmp->~T();
  --num;
  ++tmp;
 }
 Dealloc((int*)ptr-1);
}
#include "MemoryManager.h"                   //.cpp文件
list<BlockInfo> BlockList;
void* Alloc(size_t size, const char* file, int line)
{
 void* ptr = malloc(size);
 if(ptr != NULL)
 {
  BlockInfo info(ptr,file,line);
  BlockList.push_back(info);
 }
 return ptr;
}
void Dealloc(void* ptr)
{
 free(ptr);
 if(ptr != NULL)
 {
  list<BlockInfo>::iterator it = BlockList.begin();
  while(it != BlockList.end())
  {
   if(it->_ptr == ptr)
   {
    BlockList.erase(it);
    return;
   }
   ++it;
  }
  assert(false);
 }
}
void Print()
{
 cout<<"内存泄露的内存块:"<<endl;
 list<BlockInfo>::iterator it = BlockList.begin();
 while(it != BlockList.end())
 {
  printf("ptr:%p\tfile:%s\tline:%d\n",it->_ptr,it->_file.c_str(),it->_line);
  ++it;
 }
}