1. 程式人生 > >檢測記憶體洩漏的方法

檢測記憶體洩漏的方法

  1 #include<iostream>  2 usingnamespace std;
  3 //---------------------------------------------------------------
  4 // 記憶體記錄
  5 //---------------------------------------------------------------  6 class MemInfo {
  7 private:
  8 void* ptr;
  9 constchar* file;
 10   unsigned int line;
 11   MemInfo* link;
 12   friend class MemStack;
 13 };
 14 //---------------------------------------------------------------
 15 // 記憶體記錄棧 
 16 //--------------------------------------------------------------- 17 class MemStack {
 18 private:
 19   MemInfo* head;
 20 public:
 21   MemStack():head(NULL) { }
 22 ~MemStack() { 
 23     MemInfo
* tmp;
 24 while(head != NULL) {
 25       free(head->ptr); // 釋放洩漏的記憶體  26       tmp = head->link;
 27       free(head);
 28       head = tmp;
 29     }
 30   }
 31 void Insert(void* ptr, constchar* file, unsigned int line) {
 32     MemInfo* node = (MemInfo*)malloc(sizeof(MemInfo));
 33     node->ptr 
= ptr; node->file = file; node->line=line;
 34     node->link = head; head = node;    
 35   }
 36 void Delete(void* ptr) {
 37     MemInfo* node = head;
 38     MemInfo* pre = NULL;
 39 while(node != NULL && node->ptr!=ptr) {
 40       pre = node;
 41       node = node->link;
 42     }
 43 if(node == NULL)
 44       cout <<"刪除一個沒有開闢的記憶體"<< endl;
 45 else {
 46 if(pre == NULL) // 刪除的是head  47         head = node->link;
 48 else 49         pre->link = node->link;
 50       free(node);
 51     }
 52   }
 53 void Print() {
 54 if(head == NULL) {
 55       cout <<"記憶體都釋放掉了"<< endl; 
 56 return;
 57     }
 58     cout <<"有記憶體洩露出現"<< endl; 
 59     MemInfo* node = head;    
 60 while(node != NULL) {
 61       cout <<"檔名: "<< node->file <<" , "<<"行數: "<< node->line <<" , " 62 <<"地址: "<< node->ptr << endl; 
 63       node = node->link;
 64     }
 65   }
 66 };
 67 //---------------------------------------------------------------
 68 // 全域性物件 mem_stack記錄開闢的記憶體 
 69 //--------------------------------------------------------------- 70 MemStack mem_stack;
 71 //---------------------------------------------------------------
 72 // 過載new,new[],delete,delete[] 
 73 //--------------------------------------------------------------- 74 void*operatornew(size_t size, constchar* file, unsigned int line) {
 75 void* ptr = malloc(size);
 76   mem_stack.Insert(ptr, file, line);
 77 return ptr;
 78 }
 79 void*operatornew[](size_t size, constchar* file, unsigned int line) {
 80 returnoperatornew(size, file, line); // 不能用new  81 }
 82 voidoperator delete(void* ptr) {
 83   free(ptr);
 84   mem_stack.Delete(ptr);
 85 }
 86 voidoperator delete[](void* ptr) {
 87 operator delete(ptr);
 88 }
 89 //---------------------------------------------------------------
 90 // 使用巨集將帶測試程式碼中的new和delte替換為過載的new和delete 
 91 //--------------------------------------------------------------- 92 #define new new(__FILE__,__LINE__) 93 //---------------------------------------------------------------
 94 // 待測試程式碼 
 95 //--------------------------------------------------------------- 96 void bad_code() {
 97 int*=newint;
 98 char*=newchar[5];
 99   delete []q;
100 
101 102 void good_code() {
103 int*=newint;
104 char*=newchar[5];
105   delete p;
106   delete []q;
107 
108 //---------------------------------------------------------------
109 // 測試過程 
110 //---------------------------------------------------------------111 int main() {
112   good_code();
113   bad_code();
114   mem_stack.Print();
115   system("PAUSE");
116 return0;
117 }