Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1844427
  • 博文数量: 274
  • 博客积分: 2366
  • 博客等级: 大尉
  • 技术积分: 1880
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-22 09:37
文章分类

全部博文(274)

文章存档

2022年(1)

2020年(10)

2019年(7)

2018年(18)

2017年(26)

2016年(32)

2015年(43)

2014年(30)

2013年(44)

2012年(36)

2011年(17)

2010年(10)

分类: LINUX

2016-01-22 00:19:45


原文  http://blog.csdn.net/zmyer/article/details/21475101
从事C++研发的筒子们,最挥之不去可能要算内存泄露带来的痛苦吧,在C++中,虽说其实现底层代码方面所凸显出来的性能要远高于其他类型语言,但是其由于缺乏天生的内存回收机制,从而也被业界予以诟病,那有没有办法能够监测到程序中的内存泄露问题呢,其实是有很多的办法,例如efence ,vagrind类型的工具等,但是这些工具最大的问题就是太重量级了,需要在自己的代码中安插部分调试代码,使用起来也是不很方便,基于此,本人通过学习前人的一些方法,稍微对new,delete进行了重载,基本上实现了检查程序中的内存泄露问题,好了,下面来看代码吧:

#include #include #include #include using namespace boost; #define MEM_CHECK_TABLESIZE 1024*1024 #define MEM_HASH_FUNC(ptr) ((reinterpret_cast(ptr))%MEM_CHECK_TABLESIZE) #define MEM_FILENAME_SIZE 1024 boost::mutex mut;
boost::mutex mem_mut; struct allocMem_ptr_t
{  allocMem_ptr_t()  {   bzero(fileName,sizeof(fileName));   size = 0;   line = 0;   next = NULL;  }  char fileName[MEM_FILENAME_SIZE];  int size;  int line;  allocMem_ptr_t* next;
}; struct allocMem_ptr_t* allocMem_list[MEM_CHECK_TABLESIZE]; int tableSize = 0; struct memLeak_ptr_t
{  memLeak_ptr_t()  {   bzero(fileName,sizeof(fileName));   size = 0;  }  char fileName[MEM_FILENAME_SIZE];  int size;
}; std::map<int,memLeak_ptr_t> memLeak_map; void memCheck()
{  size_t index = 0;  mem_mut.lock();  for(int i=0;i {   allocMem_ptr_t* alloc = allocMem_list[i];   if(NULL == alloc) continue;   while(alloc)   {    memLeak_ptr_t memLeak;    sprintf(memLeak.fileName,"%s:%d",alloc->fileName,alloc->line);    memLeak.size = alloc->size;    memLeak_map.insert(std::make_pair(index,memLeak));    alloc = alloc->next;    index++;   }  }  mem_mut.unlock();  std::map<std::string,int> leakCount;  for(int i =0;i  leakCount[memLeak_map[i].fileName] += memLeak_map[i].size;  typedef std::map<std::string,int>::iterator leakCount_iter;  for(leakCount_iter iter = leakCount.begin();iter != leakCount.end();++iter)  {   printf("%s LEAK MEMORY SIZE:%d\n",iter->first.c_str(),iter->second);  }
} void* operator new(size_t size,const char* file,int line)
{  size_t siz = size + sizeof(allocMem_ptr_t);  allocMem_ptr_t* ptr = (allocMem_ptr_t*)::malloc(siz);  if(NULL == ptr) abort();  void* p = (char*)ptr + sizeof(allocMem_ptr_t);  strncpy(ptr->fileName,file,MEM_FILENAME_SIZE-1);  ptr->size = size;  ptr->line = line;  mem_mut.lock();  size_t index = MEM_HASH_FUNC(p);  ptr->next = allocMem_list[index];  allocMem_list[index] = ptr;  ++tableSize;  mem_mut.unlock();  return p;
} void* operator new[](size_t size,const char* file,int line)
{  return operator new(size,file,line);
} void operator delete(void* ptr)
{  if(NULL == ptr) return;  allocMem_ptr_t* pre = NULL;  size_t index = MEM_HASH_FUNC(ptr);  mem_mut.lock();  allocMem_ptr_t* pointer = allocMem_list[index];  while(pointer)  {   if((char*)pointer + sizeof(allocMem_ptr_t) == ptr)   {    if(NULL == pre)     allocMem_list[index] = pointer->next;    else     pre->next = pointer->next;    --tableSize;    break;   }   pre = pointer;   pointer = pointer->next;  }  mem_mut.unlock();  free(pointer);
} void operator delete[](void* pointer)
{  operator delete(pointer);
} void operator delete(void* pointer,const char* file,int line)
{  operator delete(pointer);
} void operator delete[](void* pointer,const char* file,int line)
{  operator delete(pointer);
}
#ifndef __MEM_CHECK__H #define __MEM_CHECK__H #include #include #define MEM_CHECK memCheck() void memCheck(); void* operator new(size_t size,const char* file,int line); void* operator new[](size_t size,const char* file,int line); void operator delete(void* pointer,const char* file,int line); void operator delete[](void* pointer,const char* file,int line); #define MEM_ALLOC new(__FILE__,__LINE__) #define MEM_DELETE delete #endif

测试程序:

#include "MemCheck.h" struct point
{  point()  {   posX = 0;   posY = 0;  }  int posX;  int posY;
}; int main(int argc,char* argv[])
{  int* pointer = MEM_ALLOC int();  double* doub = MEM_ALLOC double();  std::string* str = MEM_ALLOC std::string();  point* po = MEM_ALLOC point();  MEM_DELETE pointer;  MEM_DELETE po;  MEM_CHECK;  return 0;
}

测试结果:

Test.cpp:18 LEAK MEMORY SIZE:8 Test.cpp:19 LEAK MEMORY SIZE:4

总结

       本篇博文主要是通过封装new、delete操作,实现了一个简单版的检查内存泄露工具,原理很简单:通过一个简单的hash表来存放相关的内存分配信息,这个hash表会随着内存分配操作而动态的调整,这个实现思路其实还是有部分的问题,但总体上来将还是应用于实际的项目,好好地体会吧,有机会的话,我们可以使用redis来改写下这个功能,好了,本篇博文到此结束。

如果需要,请注明转载,多谢 

阅读(1178) | 评论(0) | 转发(0) |
0

上一篇:内存泄露

下一篇:Linux下VFP NEON浮点编译

给主人留下些什么吧!~~