功能:
    用于检測c++程序的内存泄露。
    原理: 
    事实上非常easy,就是通过函数的重载机制,捕获应用程序的new, new[] , delete , delete[], malloc,calloc,free等内存操作函数。 
    特点: 
    因为在检測的过程中,须要记录用户程序内存分配信息,所以工具本身必须进行内存动态分配。为了提高内存分配效率,程序实现了两个链表。 
    1、空暇链表,事实上就是一个简单的内存池 
 //定义一个结构,保存内存分配信息
 typedef struct _tagMemoryInfo
 {
 ??? void* addr;????????? //保存分配的内存地址 
 ??? size_t size;???????? //内存大小 
 ??? _UL lineNum;????? //调用内存分配函数的行号 
 ??? char fileName[MAX_FILE_LEN];? //文件名 
 }MemoryInfo; 
 //内存分配信息的链表结构,这里之所以定义为union类型,是为了省去next成员的开销
 union FreeList
 {
 ??? FreeList* next; 
 ??? MemoryInfo data; 
 };
    2、当前正在保存内存信息的链表 
 typedef struct _tagBusyList
 {
 ??? _tagBusyList* next; 
 ??? MemoryInfo* data; 
 }BusyList;
    不足: 
    1、仅仅是在vc2005上測试通过,没有在其它平台上測试过 
    2、不支持多线程(兴许有可能支持) 
    3、保存当前内存分配信息的链表,存在next字段的内存开销。 
    源码: 
    1、头文件 
 #ifdef DETECT_MEMORY_LEAK
 #ifndef _DETECT_MEMORY_LEAK_H_
 #define _DETECT_MEMORY_LEAK_H_
 typedef unsigned long _UL;
 void* __cdecl operator new(unsigned int size , _UL lineNum , const char* file);
 void* __cdecl operator new[](unsigned int size , _UL lineNum , const char* file);
 void __cdecl operator delete(void *p);
 void __cdecl operator delete [] (void *p);
 void __cdecl operator delete(void *p ,? _UL lineNum , const char* file);
 void __cdecl operator delete [] (void *p ,? _UL lineNum , const char* file);
 void* __cdecl _DebugMalloc(size_t size , _UL lineNum , const char* file);
 void* __cdecl _DebugCalloc(size_t num , size_t size , _UL lineNum , const char* file);
 void? __cdecl _DebugFree(void* addr);
 #ifndef DETECT_MEMORY_LEAK_IMPL
 #define new DEBUG_NEW
 #define DEBUG_NEW new(__LINE__ , __FILE__)
 #define malloc DEBUG_MALLOC
 #define DEBUG_MALLOC(x) _DebugMalloc(x , __LINE__ , __FILE__)
 #define calloc DEBUG_CALLOC
 #define DEBUG_CALLOC(x) _DebugCalloc(x , __LINE__ , __FILE__)
 #define free DEBUG_FREE
 #define DEBUG_FREE(x) _DebugFree(x)
 #endif
 void DumpLeakedMemoryInfo();
 #endif//_DETECT_MEMORY_LEAK_H_
 #endif//DETECT_MEMORY_LEAK 
   2、源文件
 #define MAX_FILE_LEN 128
 //须要实现的功能
 //1 将分配的内存信息写入文件
 //2 将释放的内存信息写入文件
 //3 将分配的内存信息都保存到内存中,提供一个接口将当前的内存泄露情况报告出去。
 //定义一个结构,保存内存分配信息
 typedef struct _tagMemoryInfo
 {
 ??? void* addr;????????? //保存分配的内存地址
 ??? size_t size;???????? //内存大小
 ??? _UL lineNum;????? //调用内存分配函数的行号
 ??? char fileName[MAX_FILE_LEN];? //文件名
 }MemoryInfo;
 //内存分配信息的链表结构,这里之所以定义为union类型,是为了省去next成员的开销
 union FreeList
 {
 ??? FreeList* next;
 ??? MemoryInfo data;
 };
 typedef struct _tagBusyList
 {
 ??? _tagBusyList* next;
 ??? MemoryInfo* data;
 }BusyList;
 //空暇链表的初始长度
 #define FREE_LIST_INIT_LEN 16
 //空暇链表的头指针
 static FreeList* g_freeList = NULL;
 //正在使用链表的头指针
 static BusyList* g_busyList = NULL;
 //内部使用函数的声明
 static void _CreateFreeList(int initLen);
 static void _ReleaseFreeList();
 static void* _GetFreeNode();
 static void* _GetBusyNode();
 static void _FreeNode(void* p);
 static void _WriteMemoryInfo(const MemoryInfo* pInfo , bool bAlloc);
 static void _StoreMemoryAllocInfo(void* addr , size_t size , _UL lineNum , const char* file);
 static void _StoreMemoryDeallocInfo(void* addr);
 void* __cdecl operator new(unsigned int size , _UL lineNum , const char* file)
 {
 ??? void* p = ::operator new(size);
 ??? _StoreMemoryAllocInfo(p , size , lineNum , file);
 ??? return p;
 ??? //return 0;
 }
 void __cdecl operator delete(void* p)
 {
 ? _StoreMemoryDeallocInfo(p);
 }
 void __cdecl operator delete(void *p,? _UL lineNum , const char* file)
 {
 ??? lineNum;
 ? file;
 ??? _StoreMemoryDeallocInfo(p);
 }
 void* __cdecl operator new[](unsigned int size , _UL lineNum , const char* file)
 {
 ??? void* p = ::operator new(size);
 ??? 
 ??? _StoreMemoryAllocInfo(p , size , lineNum , file);
 ??? 
 ??? return p;???
 }
 void __cdecl operator delete [] (void *p)
 {
 ??? _StoreMemoryDeallocInfo(p);
 }
 void __cdecl operator delete [] (void *p ,? _UL lineNum , const char* file)
 {
 ? lineNum;
 ? file;
 ? _StoreMemoryDeallocInfo(p);
 }
 void* __cdecl _DebugMalloc(size_t size , _UL lineNum , const char* file)
 {
 ??? void* p = malloc(size);
 ? _StoreMemoryAllocInfo(p , size , lineNum , file);
 ? return p;
 }
 void* __cdecl _DebugCalloc(size_t num , size_t size , _UL lineNum , const char* file)
 {
 ? void* p = calloc(num , size);
 ? _StoreMemoryAllocInfo(p , num * size , lineNum , file);
 ? return p;
 }
 void? __cdecl _DebugFree(void* addr)
 {?
 ? _StoreMemoryDeallocInfo(addr);?
 }
 //创建一个空暇节点链表,生成一个内存池,用以记录内存分配信息。
 //这样当频繁分配内存的时候,不会由于检測工具本身的性能,影响应用程序的性能。
 void _CreateFreeList(int initLen)
 {
 ??? FreeList* p = (FreeList*)malloc(sizeof(FreeList) * initLen);
 ??? g_freeList = p;
 ??? for (int idx = 1; idx < initLen; ++idx)
 ??? {
 ??????? p->next = p + idx;
 ??????? p++;
 ??? }
 ??? p->next = NULL;
 }
 void* _GetFreeNode()
 {
 ??? if ( g_freeList == NULL)
 ??? {
 ??????? _CreateFreeList(FREE_LIST_INIT_LEN);
 ??????? if ( NULL == g_freeList )
 ??????? {
 ??????????? return NULL;
 ??????? }
 ??? }
 ??? 
 ??? FreeList* p = g_freeList;???
 ??? g_freeList = g_freeList->next;
 ??? return (void*)p;
 } 
 void* _GetBusyNode(void* addr)
 {
 ? if ( g_busyList == NULL)
 ? {
 ?? return NULL;
 ? }
 ? if ( NULL == g_busyList->next)
 ? {
 ?? MemoryInfo* retNode = NULL;
 ?? if (g_busyList->data->addr == addr)
 ?? {
 ??? retNode = g_busyList->data;
 ??????????? delete g_busyList;
 ??? g_busyList = NULL;???????????
 ?? }
 ? 
 ?? return (void*)retNode;
 ? }
 ? BusyList* pre , *curr;
 ? pre = curr = g_busyList;
 ? while(curr)
 ? {
 ?? if (curr->data->addr == addr)
 ?? {
 ??? BusyList* tmp = curr;
 ??? MemoryInfo* retNode = curr->data;
 ??? pre->next = curr->next;
 ??? free((void*)tmp);
 ??? return (void*)retNode;
 ?? }
 ?? pre = curr;
 ?? curr = curr->next;
 ? }
 ??? return NULL;
 }
 void _FreeNode(void* p)
 {
 ??? if ( NULL == p)
 ??? {
 ??????? return;
 ??? }
 ??? FreeList* tmpNode = (FreeList*)p;
 ??? tmpNode->next = g_freeList;
 ??? g_freeList = tmpNode;
 }
 //保存内存分配信息
 void _StoreMemoryAllocInfo(void* addr , size_t size , _UL lineNum , const char* file)
 {
 ??? MemoryInfo* node = (MemoryInfo*)_GetFreeNode();
 ??? if ( NULL == node )
 ??? {
 ??????? return;
 ??? }
 ??? node->addr =addr;
 ??? node->size = size;
 ??? node->lineNum = lineNum;
 ?? 
 ??? size_t len = strlen(file);
 ??? len = len >= MAX_FILE_LEN ? MAX_FILE_LEN - 1 : len;
 ??? strncpy(node->fileName , file , len);
 ? node->fileName[len] = '/0';
 ??? //增加链表
 ??? BusyList* busyNode = (BusyList*)malloc(sizeof(BusyList));
 ??? busyNode->data = node;
 ??? if ( g_busyList == NULL )
 ??? {
 ??????? g_busyList = busyNode;
 ??????? busyNode->next = NULL;
 ??? }
 ??? else
 ??? {
 ??????? busyNode->next = g_busyList;
 ??????? g_busyList = busyNode;
 ??? }
 ??? //写入文件
 ??? _WriteMemoryInfo(node , true);
 }
 //保存内存分配信息
 void _StoreMemoryDeallocInfo(void* addr)
 {
 ? MemoryInfo* node = (MemoryInfo*)_GetBusyNode(addr);
 ? if ( NULL == node )
 ? {
 ?? return;
 ? }
 ? //写入文件
 ? _WriteMemoryInfo(node , false);
 ??? _FreeNode((void*)node);?
 }
 //写日志函数
 void _WriteMemoryInfo(const MemoryInfo* pInfo , bool bAlloc)
 {
 ??? if (pInfo != NULL)
 ??? {
 ??????? FILE *fp = fopen("debugmemorylog.txt","a+");
 ??????? if (!fp)
 ??????????? return;
 ??????? fprintf(fp,"%p:/t%s/t%d line %s %d bytes/n",pInfo->addr, pInfo->fileName, pInfo->lineNum /
 ??????????? , (bAlloc ? "allocated" : "freed") , pInfo->size);
 ??????? fflush(fp);
 ??????? fclose(fp);
 ??? }
 }
 //将泄露的内存信息写到磁盘
 void DumpLeakedMemoryInfo()
 {
 ? FILE *fp = fopen("memoryleak.txt","a+");
 ? if (!fp)
 ?? return;
 ? 
 ? BusyList* p = g_busyList;
 ? while (p)
 ? {
 ?? BusyList* tmp = p;
 ?? MemoryInfo* pInfo = tmp->data;
 ?? if (pInfo != NULL)
 ?? {???
 ??? fprintf(fp,"%p:/t%s/t%d line leak %d bytes/n",pInfo->addr, pInfo->fileName, pInfo->lineNum , pInfo->size);???
 ?? }
 ?? _FreeNode((void*)pInfo);
 ?????? delete tmp;
 ??? tmp = NULL;
 ??? p = p->next;
 ? }
 ? fflush(fp);
 ? fclose(fp);
 ? //释放内存池资源给操作系统
 ??? _ReleaseFreeList();
 }
 void _ReleaseFreeList()
 {
 ??? while(g_freeList)
 ? {
 ?? FreeList* tmp = g_freeList->next;
 ?? delete g_freeList;
 ?? g_freeList = tmp;??
 ? }
 }
 #endif//DETECT_MEMORY_LEAK 
 
                            