檢測記憶體洩漏的方法
阿新 • • 發佈:2019-02-05
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*p =newint;
98 char*q =newchar[5];
99 delete []q;
100 }
101 102 void good_code() {
103 int*p =newint;
104 char*q =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 }
3 //---------------------------------------------------------------
4 // 記憶體記錄
5 //--------------------------------------------------------------- 6 class MemInfo {
7 private:
8 void* ptr;
9 constchar* file;
10 unsigned int line;
11 MemInfo* link;
13 };
14 //---------------------------------------------------------------
15 // 記憶體記錄棧
16 //--------------------------------------------------------------- 17 class MemStack {
18 private:
19 MemInfo* head;
20 public:
21 MemStack():head(NULL) { }
22 ~MemStack() {
23 MemInfo
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
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*p =newint;
98 char*q =newchar[5];
99 delete []q;
100 }
101 102 void good_code() {
103 int*p =newint;
104 char*q =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 }