C++簡單記憶體流失檢查機制實現

來源:互聯網
上載者:User

  這裡是一個簡單的記憶體流失自動檢查機制。只適用於單線程情況下。工作原理就是將已經分配的記憶體用一個雙向鏈表串聯起來,釋放記憶體時從鏈表裡刪除。在程式退出時,將鏈表中未釋放的記憶體列印出來。同時在記憶體塊中儲存檔案名稱和行號,用於定位記憶體配置地址。

  001 // placement_new.cpp : Defines the entry point for the console application.

  002 //

  003

  004 #include "stdafx.h"

  005 #include

  006 #include

  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 C++ountOfAllocatedMem(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 {

  091 public:

  092 Object()

  093 {

  094 cout << "Object's contructor." << endl;

  095 }

  096

  097 ~Object()

  098 {

  099 cout << "Object's destructor." << endl;

  100 }

  101

  102 char data[1024];

  103 };

  104

  105 #define NEW new(__FILE__, __LINE__)

  106

  107 int _tmain(int argc, _TCHAR* argv[])

  108 {

  109 ASSERT(CountOfAllocatedMem() == 0);

  110 Object* pObj = new(buff) Object;

  111

  112 pObj->~Object();

  113

  114 pObj = NEW(Object);

  115 ASSERT(CountOfAllocatedMem() == 1);

  116

  117 delete pObj;

  118 ASSERT(CountOfAllocatedMem() == 0);

  119

  120 pObj = NEW Object;

  121 ASSERT(CountOfAllocatedMem() == 1);

  122 delete pObj;

  123 ASSERT(CountOfAllocatedMem() == 0);

  124

  125 pObj = NEW Object;

  126

  127 char* p = new char[968];

  128 ASSERT(CountOfAllocatedMem() == 2);

  129

  130 DumpUnAllocatedMem();

  131 return 0;

  132 }

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.