免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
C 的內(nèi)存管理

C++的內(nèi)存管理

分類: C/C++10691人閱讀評(píng)論(95)收藏舉報(bào)

目錄(?)[+]

這篇文章是我在學(xué)習(xí)指針以及內(nèi)存分配,但我感覺那篇還不是很好,這篇我很把它更完善一些

一.內(nèi)存的常見分配方式

  1. 從靜態(tài)區(qū)分配,一般是全局變量和static類型變量

  2.從棧區(qū)分配內(nèi)存,一般是局部的變量,會(huì)隨著所在函數(shù)的結(jié)束而自動(dòng)釋放

  3.從堆中分配,一般是使用手動(dòng)分配,使用malloc()函數(shù)和new來申請(qǐng)任意大小空間,不過要手動(dòng)釋放空間,相應(yīng)的使用free()函數(shù)和delete釋放,

    如果不釋放該空間,而且指向該空間的指針指向了別的空間.則該空間就無法釋放,造成內(nèi)存泄露,造成了內(nèi)存浪費(fèi)

二.內(nèi)存的使用規(guī)則

  1.在使用malloc()或new申請(qǐng)空間時(shí),要檢查有沒有分配空間成功,判斷方法是判斷指針是否為NULL,如申請(qǐng)一塊很大的內(nèi)存而沒有這么大的內(nèi)存則分配內(nèi)存會(huì)失敗

  2.申請(qǐng)成功后最好是將該內(nèi)存清空,使用memset()后ZeroMemory()清空,不然存在垃圾而造成有時(shí)候輸出很大亂碼

  3.不要忘記為數(shù)組和動(dòng)態(tài)內(nèi)存賦初值。防止將未被初始化的內(nèi)存作為右值使用。(這句話不太理解)

  4.要防止數(shù)組或指針內(nèi)存越界,

  5.申請(qǐng)內(nèi)存成功后,使用結(jié)束后要釋放,系統(tǒng)不會(huì)自動(dòng)釋放手動(dòng)分配的內(nèi)存

  6.內(nèi)存釋放后,指針還是指向那塊地址,不過這指針已經(jīng)是"野指針"了,所以釋放內(nèi)存后指針要指向NULL,不然很危險(xiǎn),容易出錯(cuò),if()對(duì)野指針的判斷不起作用

三.指針和數(shù)組

  1. 數(shù)組里的數(shù)據(jù)可以單個(gè)修改,但指針的不行,如我的例子,char str[] = "hello",數(shù)組的大小有6個(gè)字符(注意\0),可以通過str[0] = 'X'修改了的個(gè)字符,而指針

char *p = "Word",p是指向了一串常量的字符串,常量字符串是不可修改的,如 p[0] = 'X',編譯器編譯時(shí)不會(huì)保存,但執(zhí)行時(shí)會(huì)出錯(cuò)

 

 

   2.內(nèi)容的復(fù)制與比較

   內(nèi)容的復(fù)制要使用strcpy()函數(shù),不要使用賦值符"=",內(nèi)容的比較也是不要使用比較符號(hào)"<,>,==",使用strcmp()函數(shù)

  1. // 數(shù)組…  
  2.   
  3.     char a[] = "hello";  
  4.   
  5.     char b[10];  
  6.   
  7.     strcpy(b, a);           // 不能用   b = a;  
  8.   
  9.     if(strcmp(b, a) == 0)   // 不能用  if (b == a)  

  1. // 指針…  
  2.   
  3.    int len = strlen(a);  
  4.   
  5.    char *p = (char *)malloc(sizeof(char)*(len+1));  
  6.   
  7.    strcpy(p,a);            // 不要用 p = a;  
  8.   
  9.    if(strcmp(p, a) == 0)   // 不要用 if (p == a)  

    3,計(jì)算空間的大小

 對(duì)數(shù)組的計(jì)算是使用sizeof()函數(shù),該函數(shù)會(huì)按照內(nèi)存對(duì)齊的方式4的倍數(shù)計(jì)算,而指針的空間大小沒法計(jì)算,只能記住在申請(qǐng)空間時(shí)的空間大小

注意當(dāng)數(shù)組作為函數(shù)的參數(shù)進(jìn)行傳遞時(shí),該數(shù)組自動(dòng)退化為同類型的指針,不論數(shù)組a的容量是多少,sizeof(a)始終等于sizeof(char *)

 

 

  1. void Func(char a[100])  
  2.   
  3.     {  
  4.   
  5.         cout<< sizeof(a) << endl;   // 4字節(jié)而不是100字節(jié)  
  6.   
  7. }  


 

四.指針的內(nèi)存的傳遞

如果函數(shù)的參數(shù)是指針,則不要使用該參數(shù)來申請(qǐng)內(nèi)存空間,這樣沒有實(shí)際的用處,而且這樣當(dāng)函數(shù)結(jié)束時(shí)還得不到釋放內(nèi)存而造成內(nèi)存泄露

 

     這個(gè)問題可以使用"指針的指針"的方法可以解決,不然使用返回指針地址的辦法,先看一下使用 "指針的指針"方法,

還可以考慮一下引用

 

 

使用返回內(nèi)存地址的方法

 

 使用返回的方式傳遞內(nèi)存地址容易出錯(cuò)的地方在于放回"棧內(nèi)存"的指針,當(dāng)GetMemory()函數(shù)結(jié)束時(shí)棧內(nèi)存也被釋放,

 

 

 像這個(gè)代碼

  1. char *GetString2(void)  
  2.   
  3. {  
  4.   
  5.     char *p = "hello world";  
  6.   
  7.     return p;  
  8.   
  9. }  
  10.    
  11. void Test5(void)  
  12.   
  13. {  
  14.   
  15.     char *str = NULL;  
  16.   
  17.     str = GetString2();  
  18.   
  19.     cout<< str << endl;  
  20.   
  21. }  
  22.    

函數(shù)Test5運(yùn)行雖然不會(huì)出錯(cuò),但是函數(shù)GetString2的設(shè)計(jì)概念卻是錯(cuò)誤的。因?yàn)镚etString2內(nèi)的“hello world”是常量字符串,位于靜態(tài)存儲(chǔ)區(qū),

它在程序生命期內(nèi)恒定不變。無論什么時(shí)候調(diào)用GetString2,它返回的始終是同一個(gè)“只讀”的內(nèi)存塊。

 

五.動(dòng)態(tài)內(nèi)存釋放問題與野指針

   1. 當(dāng)我們使用free()和delete釋放一塊內(nèi)存時(shí),指針還是指向原來的地址,不過這時(shí)候的指針時(shí)野指針,

可以驗(yàn)證一下.這圖是我調(diào)試到if()語句時(shí)的情況,p還沒有指向NULL,只是釋放了p指向的空間了

 

 

 

執(zhí)行的結(jié)果可以看看...

 

 

所以有這樣的一些特征:

1.指針銷毀了,并不表示所指的空間也得到了釋放 :內(nèi)存泄露

2.內(nèi)存被釋放了,并不表示指針也被銷毀了或指向NULL :野指針

 

六.malloc()/free()與new/delete的區(qū)別(摘抄原文)

malloc與free是C++/C語言的標(biāo)準(zhǔn)庫函數(shù),new/delete是C++的運(yùn)算符。它們都可用于申請(qǐng)動(dòng)態(tài)內(nèi)存和釋放內(nèi)存。對(duì)于非內(nèi)部數(shù)據(jù)類型的對(duì)象而言,

光用maloc/free無法滿足動(dòng)態(tài)對(duì)象的要求。對(duì)象在創(chuàng)建的同時(shí)要自動(dòng)執(zhí)行構(gòu)造函數(shù),對(duì)象在消亡之前要自動(dòng)執(zhí)行析構(gòu)函數(shù)。由于malloc/free是庫函

數(shù)而不是運(yùn)算符,不在編譯器控制權(quán)限之內(nèi),不能夠把執(zhí)行構(gòu)造函數(shù)和析構(gòu)函數(shù)的任務(wù)強(qiáng)加于malloc/free。

因此C++語言需要一個(gè)能完成動(dòng)態(tài)內(nèi)存分配和初始化工作的運(yùn)算符new,以及一個(gè)能完成清理與釋放內(nèi)存工作的運(yùn)算符delete。注意new/delete不是庫函數(shù)。

我們先看一看malloc/free和new/delete如何實(shí)現(xiàn)對(duì)象的動(dòng)態(tài)內(nèi)存管理,看代碼

  1. class Obj  
  2.   
  3. {  
  4.   
  5. public :  
  6.   
  7.         Obj(void){ cout << “Initialization” << endl; }  
  8.   
  9.         ~Obj(void){ cout << “Destroy” << endl; }  
  10.   
  11.         void    Initialize(void){ cout << “Initialization” << endl; }  
  12.   
  13.         void    Destroy(void){ cout << “Destroy” << endl; }  
  14.   
  15. };  
  16.    
  17. void UseMallocFree(void)  
  18.   
  19. {  
  20.   
  21.     Obj  *a = (obj *)malloc(sizeof(obj));   // 申請(qǐng)動(dòng)態(tài)內(nèi)存  
  22.   
  23.     a->Initialize();                        // 初始化  
  24.   
  25.     //…  
  26.   
  27.     a->Destroy();   // 清除工作  
  28.   
  29.     free(a);        // 釋放內(nèi)存  
  30.   
  31. }  
  32.    
  33. void UseNewDelete(void)  
  34.   
  35. {  
  36.   
  37.     Obj  *a = new Obj;  // 申請(qǐng)動(dòng)態(tài)內(nèi)存并且初始化  
  38.   
  39.     //…  
  40.   
  41.     delete a;           // 清除并且釋放內(nèi)存  
  42.   
  43. }  
  44.    

       類Obj的函數(shù)Initialize模擬了構(gòu)造函數(shù)的功能,函數(shù)Destroy模擬了析構(gòu)函數(shù)的功能。函數(shù)UseMallocFree中,由于malloc/free不能執(zhí)行構(gòu)造函數(shù)與析構(gòu)函數(shù),必須調(diào)用成員函數(shù)Initialize和Destroy來完成初始化與清除工作。函數(shù)UseNewDelete則簡單得多。

       所以我們不要企圖用malloc/free來完成動(dòng)態(tài)對(duì)象的內(nèi)存管理,應(yīng)該用new/delete。由于內(nèi)部數(shù)據(jù)類型的“對(duì)象”沒有構(gòu)造與析構(gòu)的過程,對(duì)它們而言malloc/free和new/delete是等價(jià)的。

    既然new/delete的功能完全覆蓋了malloc/free,為什么C++不把malloc/free淘汰出局呢?這是因?yàn)镃++程序經(jīng)常要調(diào)用C函數(shù),而C程序只能用malloc/free管理動(dòng)態(tài)內(nèi)存。

如果用free釋放“new創(chuàng)建的動(dòng)態(tài)對(duì)象”,那么該對(duì)象因無法執(zhí)行析構(gòu)函數(shù)而可能導(dǎo)致程序出錯(cuò)。如果用delete釋放“malloc申請(qǐng)的動(dòng)態(tài)內(nèi)存”,理論上講程序不會(huì)出錯(cuò),但是該程序的可讀性很差。所以new/delete必須配對(duì)使用,malloc/free也一樣。

 

 七.如何處理內(nèi)存耗盡

   1.判斷指針是否為NULL,如果是則馬上用return語句終止本函數(shù)

   2.判斷指針是否為NULL,如果是則馬上用exit(1)終止整個(gè)程序的運(yùn)行

   3.為new和malloc設(shè)置異常處理函數(shù)。例如Visual C++可以用_set_new_hander函數(shù)為new設(shè)置用戶自己定義的異常處理函數(shù),

      也可以讓malloc享用與new相同的異常處理函數(shù)

malloc()/free()和new/delete的使用要點(diǎn)網(wǎng)上有更詳細(xì)的說明

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
C 內(nèi)存管理詳解
內(nèi)存溢出總結(jié):
高質(zhì)量C/C++編程(片段)
C++內(nèi)存管理詳解(3)
[轉(zhuǎn)載]C++指針new和malloc區(qū)別
new/delete 和malloc/free 的區(qū)別一般匯總
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服