new和malloc的區別

2021-09-12 13:46:09 字數 4275 閱讀 4877

2. new運算子

3. malloc和new的區別

4. 有了malloc/free為什麼還要new/delete?

malloc 的全稱是 memory allocation,中文叫動態記憶體分配。

原型:extern void *malloc(unsigned int num_bytes);

說明:分配長度為 num_bytes 位元組的記憶體塊。如果分配成功則返回指向被分配記憶體的指標,分配失敗返回空指標 null。當記憶體不再使用時,應使用 free() 函式將記憶體塊釋放。

返回型別是 void* 型別。void* 表示未確定型別的指標。c,c++ 規定,void* 型別可以強制轉換為任何其它型別的指標。

void* 表示未確定型別的指標,更明確的說是指申請記憶體空間時還不知道使用者是用這段空間來儲存什麼型別的資料(比如是 char 還是 int 或者…)

void free(void *firstbyte);

該函式是將之前用 malloc 分配的空間還給程式或者是作業系統,也就是釋放了這塊記憶體,讓它重新得到自由,可以被重新分配和使用。

1)申請了記憶體空間後,必須檢查是否分配成功

2)當不需要再使用申請的記憶體時,記得釋放;釋放後應該把指向這塊記憶體的指標指向null,防止程式後面不小心使用了它。

3)這兩個函式應該是配對。如果申請後不釋放就是記憶體洩露;如果無故釋放那就是什麼也沒有做。釋放只能一次,如果釋放兩次及兩次以上會出現錯誤(釋放空指標例外,釋放空指標其實也等於啥也沒做,所以釋放空指標釋放多少次都沒有問題)。

4)雖然 malloc() 函式的型別是 void * ,任何型別的指標都可以轉換成 void * ,但是最好還是在前面進行強制型別轉換,因為這樣可以躲過一些編譯器的檢查。

答案是從堆裡面獲得空間。也就是說函式返回的指標是指向堆裡面的一塊記憶體

作業系統中有乙個記錄空閒記憶體位址的鍊錶。當作業系統收到程式的申請時,就會遍歷該鍊錶,然後就尋找第乙個空間大於所申請空間的堆結點,然後就將該結點從空閒結點鍊錶中刪除,並將該結點的空間分配給程式。

動態建立物件時,只需指定其資料型別,而不必為該物件命名,new表示式返回指向該新建立物件的指標,我們可以通過指標來訪問此物件。

int *pi = new int;

這個 new 表示式在堆區中分配建立了乙個整型物件,並返回此物件的位址,並用該位址初始化指標 pi 。

動態建立的物件可以用初始化變數的方式初始化。

int *pi=new int(100);//指標pi所指向的物件初始化為100

string *ps=new string(10,』9』);//*ps 為「9999999999」

如果不提供顯示初始化,對於類型別,用該類的預設建構函式初始化;而內建型別的物件則無初始化。

也可以對動態建立的物件做值初始化:

int *pi=new int( );//初始化為0

int *pi=new int;//pi 指向乙個沒有初始化的int

string *ps=new string( );//初始化為空字串 (對於提供了預設建構函式的類型別,沒有必要對其物件進行值初始化)

delete 表示式釋放指標指向的位址空間。

delete pi ;// 釋放單個物件

delete [ ] pi;//釋放陣列

如果指標指向的不是 new 分配的記憶體位址,則使用 delete 是不合法的。

delete p; //執行完該語句後,p 變成了不確定的指標,在很多機器上,儘管 p 值沒有明確定義,但仍然存放了它之前所指物件的位址,然後 p 所指向的記憶體已經被釋放了,所以 p 不再有效。此時,該指標變成了懸垂指標(懸垂指標指向曾經存放物件的記憶體,但該物件已經不存在了)。懸垂指標往往導致程式錯誤,而且很難檢測出來。

一旦刪除了指標所指的物件,立即將指標置為 0,這樣就非常清楚的指明指標不再指向任何物件。(零值指標:int *ip = 0;)

1993 年前,c++ 一直要求在記憶體分配失敗時 operator new 要返回 0,現在則是要求 operator new丟擲 std::bad_alloc 異常。很多 c++ 程式是在編譯器開始支援新規範前寫的。c++ 標準委員會不想放棄那些已有的遵循返回 0 規範的**,所以他們提供了另外形式的 operator new ( 以及operator new )以繼續提供返回 0 功能。這些形式被稱為「無丟擲」,因為他們沒用過乙個throw,而是在使用new的入口點採用了nothrow 物件:

class widget ;

widget *pw1 = new widget;// 分配失敗丟擲std::bad_alloc

if (pw1 == 0) … // 這個檢查一定失敗

widget *pw2 = new (nothrow) widget; // 若分配失敗返回0

if (pw2 == 0) … // 這個檢查可能會成功

new 返回指定型別的指標,並且可以自動計算所需要大小。

int p;   

p = new int;//返回型別為 int* 型別(整數型指標),分配大小為 sizeof(int);

或:   

int parr;   

parr = new int [100];//返回型別為 int* 型別(整數型指標),分配大小為 sizeof(int) * 100;

而 malloc 則必須要由我們計算位元組數,並且在返回後強行轉換為實際型別的指標。

int* p;   

p = (int *) malloc ( sizeof(int)*128 );//分配128個(可根據實際需要替換該數值)整型儲存單元,並將這128個連續的整型儲存單元的首位址儲存到指標變數p中

double *pd = (double *) malloc (sizeof(double)*12);//分配12個double型儲存單元,並將首位址儲存到指標變數pd中

malloc 只管分配記憶體,並不能對所得的記憶體進行初始化,所以得到的一片新記憶體中,其值將是隨機的。

除了分配及最後釋放的方法不一樣以外,通過 malloc 或 new 得到指標,在其它操作上保持一致。

malloc 與 free 是 c++/c 語言的標準庫函式,new/delete 是c++的運算子。它們都可用於申請動態記憶體和釋放記憶體。

對於非內部資料型別的物件而言,光用 maloc/free 無法滿足動態物件的要求。物件在建立的同時要自動執行建構函式,物件在消亡之前要自動執行析構函式。由於 malloc/free 是庫函式而不是運算子,不在編譯器控制許可權之內,不能夠把執行建構函式和析構函式的任務強加於 malloc/free。

因此 c++ 語言需要乙個能完成動態記憶體分配和初始化工作的運算子 new,以及乙個能完成清理與釋放記憶體工作的運算子delete

我們不要企圖用 malloc/free 來完成動態物件的記憶體管理,應該用 new/delete。由於內部資料型別(int、float)沒有構造與析構的過程,對它們而言 malloc/free 和 new/delete 是等價的。

既然 new/delete 的功能完全覆蓋了 malloc/free,為什麼 c++ 不把 malloc/free 淘汰出局呢?這是因為 c++ 程式經常要呼叫 c 函式,而 c 程式只能用 malloc/free 管理動態記憶體。

如果用 free 釋放 new 建立的動態物件,那麼該物件因無法執行析構函式而可能導致程式出錯。如果用 delete 釋放 malloc 申請的動態記憶體,結果也會導致程式出錯,同時該程式的可讀性很差。

所以 new/delete 必須配對使用,malloc/free 也一樣。

new和malloc的區別

1 new 是c 中的操作符,malloc是c 中的乙個函式 2 new 不止是分配記憶體,而且會呼叫類的建構函式,同理delete會呼叫類的析構函式,而malloc則只分配記憶體,不會進行初始化類成員的工作,同樣free也不會呼叫析構函式 3 記憶體洩漏對於malloc或者new都可以檢查出來的,...

malloc和new的區別

1,malloc與free是c c語言的標準庫函式,new delete是c 的運算子。它們都可用於申請動態記憶體和釋放記憶體。2,對於非內部資料型別的物件而言,光用maloc free無法滿足動態物件的要求。物件在建立的同時要自動執行建構函式,物件在消亡之前要自動執行析構函式。由於malloc f...

new 和 malloc 的區別

new 和 malloc 的區別 1.malloc與free是c c語言的標準庫函式,new delete是c 的運算子。它們都可用於申請動態記憶體和釋放記憶體。2.對於非內部資料型別的物件而言,光用maloc free無法滿足動態物件的要求。物件在建立的同時要自動執行建構函式,物件在消亡之前要自動...