内存泄漏及简单检测的一种办法   
               添加时间:2013-5-28 点击量: 
 
              1.什么是内存泄漏(Memory Leak)? 
   简单地说就是申请了一块内存空间,应用完毕后没有开释掉。它的一般发挥解析体式格式是法度运行时候越长,占用内存越多,终极用尽全部内存,全部体系溃散。由法度申请的一块内存,且没有任何一个指针指向它,那么这块内存就泄漏了。
2.内存泄漏的性
    从用户应用法度的角度来看,内存泄漏本身不会产生什么,作为一般的用户,底子感触感染不到内存泄漏的存在。真正有的是内存泄漏的聚积,这会终极消费尽体系所有的内存。首要有以下几种发挥解析情势:
1)cpu资料耗尽:估计是机械没有反响了,键盘,鼠标,以及收集等等。这个在windows上经常看见,希罕是中了毒。
2)过程id耗尽:没法创建新的过程了,串口或者telnet都没法创建了。
3)硬盘耗尽: 机械要死了,互换内存没法用,日记也没法用了,死是很正常的。
在我们写法度的时辰,一般会应用malloc,realloc,new等函数从堆平分派到一块内存,应用完后,法度必须负责响应的调用free或开释该内存块,不然,这块内存就不克不及被再次应用,我们就说这块内存泄漏了。若是要避免这个题目,还是要从代码上入手,杰出的编码习惯和规范,是避免错误的不二窍门。
3.如何检测内存泄漏?
第一:杰出的编码习惯,尽量在涉及内存的法度段,检测出内存泄漏。当程式稳定之后,在来检测内存泄漏时,无疑增长了打消的艰苦和错杂度。应用了内存分派的函数,一旦应用完毕,要记得要应用其响应的函数开释掉。
Heap memory:
malloc\realloc ------ free
new \new[] ----------  \[]
GlobalAlloc------------GlobalFree 
要希罕重视数组对象的内存泄漏
MyPointEX pointArray =new MyPointEX [100];
其删除情势为:
 []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  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.什么是内存泄漏(Memory Leak)?
2.内存泄漏的性
从用户应用法度的角度来看,内存泄漏本身不会产生什么,作为一般的用户,底子感触感染不到内存泄漏的存在。真正有的是内存泄漏的聚积,这会终极消费尽体系所有的内存。首要有以下几种发挥解析情势:
在我们写法度的时辰,一般会应用malloc,realloc,new等函数从堆平分派到一块内存,应用完后,法度必须负责响应的调用free或开释该内存块,不然,这块内存就不克不及被再次应用,我们就说这块内存泄漏了。若是要避免这个题目,还是要从代码上入手,杰出的编码习惯和规范,是避免错误的不二窍门。
3.如何检测内存泄漏?
第一:杰出的编码习惯,尽量在涉及内存的法度段,检测出内存泄漏。当程式稳定之后,在来检测内存泄漏时,无疑增长了打消的艰苦和错杂度。应用了内存分派的函数,一旦应用完毕,要记得要应用其响应的函数开释掉。
Heap memory:
malloc\realloc ------ free
new \new[] ---------- \[]
GlobalAlloc------------GlobalFree
要希罕重视数组对象的内存泄漏
MyPointEX pointArray =new MyPointEX [100];
其删除情势为:
[]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  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
我们永远不要期待别人的拯救,只有自己才能升华自己。自己已准备好了多少容量,方能吸引对等的人与我们相遇,否则再美好的人出现、再动人的事情降临身边,我们也没有能量去理解与珍惜,终将擦肩而过。—— 姚谦《品味》




