C++ new 和 malloc 的區別
阿新 • • 發佈:2021-11-21
C++ new 和 malloc 的區別
1.記憶體位置
new操作符從自由儲存區(free store)上為物件動態分配記憶體空間,而malloc函式從堆上動態分配記憶體。自由儲存區是C++基於new操作符的一個抽象概念,凡是通過new操作符進行記憶體申請,該記憶體即為自由儲存區。而堆是作業系統中的術語,是作業系統所維護的一塊特殊記憶體,用於程式的記憶體動態分配,C語言使用malloc從堆上分配記憶體,使用free釋放已分配的對應記憶體。
那麼自由儲存區是否能夠是堆(問題等價於new是否能在堆上動態分配記憶體),這取決於operator new 的實現細節。自由儲存區不僅可以是堆,還可以是靜態儲存區,這都看operator new在哪裡為物件分配記憶體。
2.返回型別
new操作符記憶體分配成功時,返回的是物件型別的指標,型別嚴格與物件匹配,無須進行型別轉換,故new是符合型別安全性的操作符。
3.分配失敗處理
new記憶體分配失敗時,會丟擲bac_alloc異常,它不會返回NULL;malloc分配記憶體失敗時返回NULL。
4.呼叫建構函式
使用new操作符來分配物件記憶體時會經歷三個步驟:
第一步:呼叫operator new 函式(對於陣列是operator new[])分配一塊足夠大的,原始的,未命名的記憶體空間以便儲存特定型別的物件。
第二步:編譯器執行相應的建構函式以構造物件,併為其傳入初值。
第三部:物件構造完成後,返回一個指向該物件的指標。
5.呼叫解構函式
使用delete操作符來釋放物件記憶體時會經歷兩個步驟:
第一步:呼叫物件的解構函式。
第二步:編譯器呼叫operator delete(或operator delete[])函式釋放記憶體空間。
綜合實踐
程式碼
#include <iostream> #include <cstdlib> #include <limits.h> #define N 10 using namespace std; int main() { // 區別1. malloc 必須強制轉換指標型別, 而 new 不用 int * p = (int *)malloc(N * sizeof(int)); int * q = new int[N]; delete [] q; free(p); // 區別2. 對於類的物件,new 會呼叫預設建構函式,而 malloc 只是單純分配空間 class Car { public: Car(){cout << "Car()" << endl;} ~Car(){cout << "~Car()" << endl;} virtual int p(){cout << "virtual p()" << endl;} private: int price; }; Car * car_p = (Car *)malloc(sizeof(Car)); Car * car_q = new Car; cout << "sizeof(Car)=" << sizeof(Car) << endl;//應該是 8, 因為一個 int 4 位元組,還有一個虛擬函式表指標 4 位元組 // 區別3. 對於類的物件,delete 會呼叫解構函式,而 free 只是單純釋放空間 delete car_q; free(car_p); // 區別4. 對分配記憶體出現錯誤時,new 會丟擲 bac_alloc 異常, malloc 會返回 NULL p = (int *)malloc(INT_MAX); if (!p) cout << "malloc failed" << endl; free(p); q = new int[INT_MAX]; delete []q; }