程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 內存洩漏及簡單檢測的一種方法,內存洩漏檢測

內存洩漏及簡單檢測的一種方法,內存洩漏檢測

編輯:C++入門知識

內存洩漏及簡單檢測的一種方法,內存洩漏檢測


1.什麼是內存洩漏(Memory Leak)? 

   簡單地說就是申請了一塊內存空間,使用完畢後沒有釋放掉。它的一般表現方式是程序運行時間越長,占用內存越多,最終用盡全部內存,整個系統崩潰。由程序申請的一塊內存,且沒有任何一個指針指向它,那麼這塊內存就洩露了。

2.內存洩漏的危害性

    從用戶使用程序的角度來看,內存洩漏本身不會產生什麼危害,作為一般的用戶,根本感覺不到內存洩漏的存在。真正有危害的是內存洩漏的堆積,這會最終消耗盡系統所有的內存。主要有以下幾種表現形式:

1)cpu資源耗盡:估計是機器沒有反應了,鍵盤,鼠標,以及網絡等等。這個在windows上經常看見,特別是中了毒。 2)進程id耗盡:沒法創建新的進程了,串口或者telnet都沒法創建了。 3)硬盤耗盡: 機器要死了,交換內存沒法用,日志也沒法用了,死是很正常的。

在我們寫程序的時候,一般會使用malloc,realloc,new等函數從堆中分配到一塊內存,使用完後,程序必須負責相應的調用free或delete釋放該內存塊,否則,這塊內存就不能被再次使用,我們就說這塊內存洩漏了。如果要避免這個問題,還是要從代碼上入手,良好的編碼習慣和規范,是避免錯誤的不二法門。

3.如何檢測內存洩漏?

第一:良好的編碼習慣,盡量在涉及內存的程序段,檢測出內存洩露。當程式穩定之後,在來檢測內存洩露時,無疑增加了排除的困難和復雜度。使用了內存分配的函數,一旦使用完畢,要記得要使用其相應的函數釋放掉。

Heap memory:

malloc\realloc ------ free

new \new[] ---------- delete \delete[]

GlobalAlloc------------GlobalFree

要特別注意數組對象的內存洩漏

MyPointEX *pointArray =new MyPointEX [100];

其刪除形式為:

delete []pointArray ;


第二:將分配的內存的指針以鏈表的形式自行管理,使用完畢之後從鏈表中刪除,程序結束時可檢查改鏈表。

第三:Boost 中的smart pointer。

第四:一些常見的工具插件,如ccmalloc、Dmalloc、Leaky等等。

4.代碼示例

    我主要想結合代碼講講第二個方法,設計思想其實很簡單,用到STL中的list。可能有人要問,為什麼不用vector呢?
list和vector的區別如下:

vector為存儲的對象分配一塊連續的地址空間,因此對vector中的元素隨機訪問效率很高。在vecotor中插入或者刪除某個元素,需要將現有元素進行復制,移動。如果vector中存儲的對象很大,或者構造函數復雜,則在對現有元素進行拷貝時開銷較大,因為拷貝對象要調用拷貝構造函數。對於簡單的小對象,vector的效率優於list。vector在每次擴張容量的時候,將容量擴展2倍,這樣對於小對象來說,效率是很高的。

list中的對象是離散存儲的,隨機訪問某個元素需要遍歷list。在list中插入元素,尤其是在首尾插入元素,效率很高,
只需要改變元素的指針。

vector適用:對象數量變化少,簡單對象,隨機訪問元素頻繁

list適用:     對象數量變化大,對象復雜,插入和刪除頻繁

1 #include <iostream> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <list> 6 7 using namespace std; 8 9 const int nMaxSize = 26; 10 struct Node 11 { 12 int count; 13 Node *next[nMaxSize]; 14 }; 15 Node *root = NULL; 16 list <Node *> nodeMemory; 17 18 void TreeCreate() 19 { 20 root = (Node *)malloc(sizeof(Node)); 21 for (int i = 0; i < nMaxSize; ++i) 22 { 23 root->next[i] = NULL; 24 } 25 } 26 27 void TreeInsert(char *pStr) 28 { 29 int i, j, len = strlen(pStr); 30 Node *p = root; 31 Node *q = NULL; 32 for (i = 0; i < len; ++i) 33 { 34 int id = pStr[i] - 'a'; 35 if (p->next[id] == NULL) 36 { 37 q = (Node *)malloc(sizeof(Node)); 38 if(q != NULL) 39 nodeMemory.push_back(q); 40 q->count = 0; 41 for (j = 0; j < nMaxSize; ++j) 42 { 43 q->next[j] = NULL; 44 } 45 p->next[id] = q; 46 } 47 p->next[id]->count++; 48 p = p->next[id]; 49 } 50 } 51 52 int TreeQuery(char *pStr) 53 { 54 int i, len = strlen(pStr); 55 int id = 0; 56 Node *p = root; 57 for (i = 0; i < len; ++i) 58 { 59 id = pStr[i] - 'a'; 60 p = p->next[id]; 61 if (p == NULL) return 0; 62 } 63 return p->count; 64 } 65 66 void TreeDelete(Node *p) 67 { 68 if (p == NULL) 69 return ; 70 for (int i = 0; i < nMaxSize; ++i) 71 { 72 TreeDelete(p->next[i]); 73 } 74 nodeMemory.remove(p); 75 free(p); 76 p = NULL; 77 } 78 79 int main(int argc, char **argv) 80 { 81 char szBuffer[16]; 82 int res = 0; 83 TreeCreate(); 84 int n = 3; 85 while (n) 86 { 87 gets(szBuffer); 88 if (strlen(szBuffer) == 0) 89 break; 90 TreeInsert(szBuffer); 91 n--; 92 } 93 /* scanf("%s", szBuffer); 94 res = TreeQuery(szBuffer); 95 printf("%d\n", res); */ 96 for(list<Node *>::iterator it = nodeMemory.begin();it != nodeMemory.end();it++) 97 { 98 cout<<*it<<endl; 99 } 100 cout<<nodeMemory.size()<<endl; 101 TreeDelete(root); 102 if(nodeMemory.empty()) 103 cout<<"has delete the tire tree"<<endl; 104 cout<<nodeMemory.size()<<endl; 105 system("pause"); 106 return 0; 107 } View Code

代碼很簡單,list存儲的是指向內存空間的指針,每次malloc之後會把這個分配的內存指針push到list中,而當free之後,list的就會刪除相應的內容,如果全釋放掉了,則list變為空,從而可以判斷使用後的內存是否全部釋放掉了?

5.最後感想

第一次在博客園發博客,之前為了方便在sina寫博客,發現sina不是一般得差,所以搬到這兒來寫了,新的開始,希望大家不吝賜教。

博客參考鏈接:

http://blog.csdn.net/na_he/article/details/7429171

http://baike.baidu.com/view/1068433.htm

http://blog.csdn.net/renkaihao/article/details/6803866

    

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved