C++简单内存泄漏检查机制实现 |
这里是一个 方便的内存 透露自动 审查机制 。只 实用于单线程状况下 。工作原理便是将已经 调配的内存用一个双向链表串联起来, 开释内存时从链表里删除 。在程序退出时,将链表中未 开释的内存打印出来 。同时在内存块中 保留文件名和行号,用于定位内存 调配地址 。 001 // placement_new.cpp : Defines the entry point for the console application. 002 // 003 004 #include "stdafx.h" 005 #include <iostream> 006 #include <cassert> 007 008 #define ASSERT assert 009 char buff[1024]; 010 011 using namespace std; 012 013 struct MEMORY_TAG 014 { 015 int nSize; 016 const char* szFile; 017 int nLine; 018 MEMORY_TAG* pPrev; 019 MEMORY_TAG* pNext; 020 }; 021 022 MEMORY_TAG g_header = {0, 0, 0, 0, 0}; 023 // 打印出全部未 开释的内存 024 void DumpUnAllocatedMem() 025 { 026 for(MEMORY_TAG* pEntry = g_header.pNext; pEntry; pEntry = pEntry->pNext) 027 { 028 printf("%s(%d) : leak %d bytes ", pEntry->szFile ? pEntry->szFile : "", pEntry->nLine, pEntry->nSize); 029 } 030 } 031 // 统计已经 调配的内存块数和字节数 032 int CountOfAllocatedMem(void* pnSize= NULL) 033 { 034 int nCount = 0; 035 size_t allocated = 0; 036 for(MEMORY_TAG* pEntry = g_header.pNext; pEntry; pEntry = pEntry->pNext) 037 { 038 allocated += pEntry->nSize; 039 nCount++; 040 } 041 printf("%d count, %d total ", nCount, allocated); 042 return nCount; 043 } 044 045 // 实现一个全局operator new 可以有文件名和行号作为参数 046 void* operator new(size_t size, const char* pszFile, int line) 047 { 048 size_t nRealSize = size + sizeof(MEMORY_TAG); 049 MEMORY_TAG* pTag = (MEMORY_TAG*)malloc(nRealSize); 050 051 pTag->nSize = nRealSize; 052 pTag->szFile = pszFile; 053 pTag->nLine = line; 054 // 插入队列头部 055 if (g_header.pNext) 056 { 057 g_header.pNext->pPrev = pTag; 058 } 059 pTag->pNext = g_header.pNext; 060 g_header.pNext = pTag; 061 pTag->pPrev = &g_header; 062 063 return pTag + 1; 064 } 065 066 void* operator new(size_t size) 067 { 068 return (operator new(size, __FILE__, __LINE__)); 069 } 070 071 072 void operator delete(void* p, const char*, int line) 073 { 074 delete p; 075 } 076 077 void operator delete(void* p) 078 { 079 MEMORY_TAG* pTag = (MEMORY_TAG*)(((char*)p)-sizeof(MEMORY_TAG)); 080 // 从队列中删除 081 pTag->pPrev->pNext = pTag->pNext; 082 if (pTag->pNext) 083 { 084 pTag->pNext->pPrev = pTag->pPrev; 085 } 086 free(pTag); 087 } 088 089 class Object 090 {
|