C++動態分配記憶體

來源:互聯網
上載者:User
為啥需要動態分配記憶體

     數組是我們常用的一種資料結構.但它有一個缺點,就是用的時候必須確定數組大小.如果我們要用數組來儲存的資料不確定可咋整啊?把數組定得太大浪費空間,太小的話又裝不下.這是一種情況.另外就是對象太大.我們使用的資料大部分時候都預設儲存在棧(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.

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.