動態內存管理

爲什麼要使用動態內存分配?

當你聲明數組時,你必須用一個編譯時常量指定數組的長度,但是,數據的長度常常在運動時才知道,這是由於它所需要的內存空間取決於輸入數據。

話說C和C++的動態內存管理有什麼區別呢?

爲什麼C語言都有了malloc/free等等,C++還需要new和delete呢?
函數原型:
malloc: void* malloc(size_t size);
calloc: void* calloc(size_t num_element,size_t element_size);
realloc:void* realloc(void* ptr,size_t new_size);

malloc:用於執行動態內存的分配,它的參數是需要分配的內存的字節數。它所分配的是一段連續的內存。
calloc:它是在malloc的基礎上對分配的內存進行初始化。
realloc:用於修改一個原先已經分配的內存塊的大小,使用這個函數,你可以使一塊內存塊擴大或者縮小,如果它用於擴大一個內存塊,那麼這個內存塊原先的內容依然保留,新開闢一塊空間未以任何方式進行初始化,如果是用於縮小一塊空間,內存塊尾的部分內存被拿掉,剩餘部分的原先內容依舊保留。使用這個函數返回的指針有的時候解引用會導致越界訪問。

C++中的new和delete是操作符。
new:在堆上開闢一塊內存,調用構造函數進行初始化。
delete:調用析構函數進行清除處理。

new是調用operator new+構造函數。
delete是調用析構函數+operator delete。

試問,爲什麼new是調用operator new,operator new再調用malloc?

因爲調用operator是保持C++的封裝,malloc開闢失敗了會返回-1,operator new開闢失敗了會拋異常。

#include<iostream>
using namespace std;
class AA
{
public:
    AA()
    {
        cout << "AA()" << endl;
    }
    ~AA()
    {
        cout << "~AA()" << endl;
    }
};
int main()
{
    AA* p1 = new AA;
    free(p1);
    //不會崩潰,但是可能會導致內存泄露。
    AA* p2 = new AA;
    delete[] p2;
    //會崩潰,是因爲在p2的面前多開了4個字節的空間。
    AA*p3 = new AA[10];
    free(p3);
    //會崩潰,沒有按照規定釋放內存。
    AA* p4 = new AA[10];
    delete[] p4;
    //正常。
    system("pause");
    return 0;
}

這裏寫圖片描述

這個是p2的畫圖。

new[]一般來說一定要多開4個字節的空間,目的就是爲了存放[N]中N的大小,但是,當編譯器識別出構造函數和析構函數可調可不調的時候,編譯器就選擇不調,所以並不需要多開4個字節的空間。
在自定義類型中,new[]用delete釋放,也不會崩潰了,但是寫了析構函數,用delete釋放就會崩潰。當析構函數沒有寫時,編譯器會認爲析構函數可調可不調。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章