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

C++動態分配內存

編輯:C++入門知識

為啥需要動態分配內存
     數組是我們常用的一種數據結構.但它有一個缺點,就是用的時候必須確定數組大小.如果我們要用數組來保存的數據不確定可咋整啊?把數組定得太大浪費空間,太小的話又裝不下.這是一種情況.另外就是對象太大.我們使用的數據大部分時候都默認保存在棧(stack)裡面,由系統去管理,會自動給分配內存,自動給刪除掉.但是stack很小,就那麼幾M,如果你讀取一個幾十M的文本內容然後保存到一個字符串裡,stack肯定會被撐爆了.

     上面說的是兩種最常見的兩種情景.另外如果你想准確的控制內存的釋放.比如內存比較緊缺,你用完一塊內存後就想立馬釋放掉.如果系統自動去釋放的話可能得等到變量生命周期結束時再釋放.不會做得到立馬釋放.

     基於上面等一些原因於是出現了堆(heap),這是由用戶自己控制的一片內存區,比stack大多了.你可以自由的在裡面申請空間釋放空間.

C語言中的動態內存分配
C語言是比較接近底層的,用它舉例說動態內存的分配更容易理解.C++是作了一定程度的封裝.就以數組來舉例吧.假如你不知道要使用的數據具體是多少,只要運行的時候才知道.就用N表示需要N個int類型的空間.於是我們需要動態的分配一塊內存,並用一個int型指針指向內存的首地址.

int n = 123;    //這裡隨便賦個值,實際使用時可能是傳個參數確定它的值

int * p = (int*)  malloc(sizeof(int)*n);

/*malloc是一個庫函數,調用它去申請內存空間,它的返回值是void*指針,所以需要做下類型轉換變成int*指針.它的參數是內存大小,以字節為單位,表示要申請多少個字節.int類型可能在不同的系統裡占用的字節不一樣,所以用sizeof計算下先. 假如你要給結構體分配內存的話,假如有結構體struct  test則是,struct test * pTest = (struct test*) malloc(sizeof(struct test));*/

現在可以把弄來的內存當數組用了.實際上也不是真的數組,只是模擬拉.

int * pArray = p;           //用另一個指針來指向p,因為p要保留著內存的首地址,這樣後面釋放內存的時候才會正確釋放

*pArray = 123;

*(pArray + 1) = 456;

free(p);      //用完了就可以這樣來釋放內存

p = 0;       //讓指針指向一塊空內存,這樣的好處有,比如你不小心在哪又再free下p就會出錯,但讓p指向空內存後多次重復free也不會出錯.

//free(p)不是釋放p指針的內存,而是以它為首地址後面的一大塊.它自己保存的地址值還是一直在那,所以你free完了後再打印p保存的地址值還跟以前一樣.

C++動態內存分配
  C++中多了個class的概念,而類裡面有個比較重要的概念是構造函數.而構造函數不能手動去調用,是實例化類時自動調用.如果像C一樣用malloc來給某個類動態分配一塊內存的話,這個類就不會調用到構造函數了.於是C++裡出現了個關鍵字new,當你使用new動態一塊內存時會自動調用構造函數(這具體咋實現的就不知道了啊.反正最後封裝成一個new給我們用).用完了釋放的話就用delete,此時會調用析構函數.

舉個例子吧假如有類Arwen

Class Arwen

{

   public:

     Arwen(string str){  name = str;}

    string name;

   ~Arwen(){ };

}

 

Arwen weiwen("csharp");    //這樣實例化一個類,是由系統在stack中分配內存並釋放內存不用我們管

Arwen*  weiwenhp = new Arwen("cplusplus"); //必須用指針Arwen*,這樣才是動態內存分配,由用戶自己去申請空間去釋放空間.

delete weiwenhp;        //釋放內存

內存洩露
動態分配內存時最容易犯的錯,也是最不容易發現的就是內存洩露了啊.

嚴格來講內洩露不是一種錯誤,它只是沒有釋放掉申請來的內存,造成了浪費而已.其實很容易用這一點來做一個病毒.你就不停的去申請內存,但都不給釋放.到最後內存就會被耗光了.

研究內存洩露是個比較復雜的話題了,會有很多種情況會導致洩露,也有很多方法去防范.

舉幾個簡單的例子瞧下

int * p = new int[88];

delete p;  //這裡就內存洩露了,要用delete []p才行.在C中就free(p)就行了

另外在函數中delete還沒執行到就退出了也容易內存洩露,比如

int function(int num)

{

         int *p = new[44];

        if( num > 111)

            return 0;

         delete []p; 

return 1;

}

如果num大於100,執行到return 0時就退出了,不會執行到delete.

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