爲什麼要使用動態內存分配?
當你聲明數組時,你必須用一個編譯時常量指定數組的長度,但是,數據的長度常常在運動時才知道,這是由於它所需要的內存空間取決於輸入數據。
話說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釋放就會崩潰。當析構函數沒有寫時,編譯器會認爲析構函數可調可不調。