天天看點

c中已經有了malloc和free,為什麼c++中會用new和delete?

要了解這個問題我們先需要了解它們的差別

相同點:都會從堆上申請空間,使用者需要自己來管理。 

不同點:

 1.所屬語言 

new是C++特性,malloc是C的。C++一般使用的new,但也可以使用malloc,而C用malloc、realloc、calloc。

2.申請釋放方式 

new和delete,malloc和free配對使用。new的使用比malloc簡單,内部已經實作了大小的計算、類型轉換等工作,而malloc使用時需要計算大小及進行類型轉換。 

3.malloc是标準庫函數,new是C++的運算符。 

new可以被重載,但malloc不可以,malloc需要庫函數的支援,new不需要。

4.構造與析構 

new和delete會自動調用構造函數和析構函數,但是malloc和free不會。

5.申請記憶體失敗 

申請記憶體失敗,預設new抛出異常,malloc傳回NULL。 

6.重新配置設定記憶體 

malloc可利用realloc重新配置設定記憶體,new不可以。 

7.類型安全性 

new會檢查類型是否對應,如果不對應會儲存,但malloc隻關注申請記憶體的多少,不會檢查類型。 

8.類型轉換 

malloc傳回的類型是void,是以在調用malloc時要進行顯式的類型轉換,将void轉換成所需的指針類型,new不需要。

9.數組配置設定 

new有明确的方式處理數組的配置設定,即new[],釋放也有delete[],malloc沒有。 

10.設定記憶體配置設定器 

new可以設定自己的記憶體配置設定器,malloc不可以。

如果上述内容你已經完全了解了,那麼請看下面的進階内容

1、new/delete、new[]/delete[]

new、delete是操作符,用來配置設定空間和清理對象的。new[]、delete[]是來為對象數組配置設定空間和清理對象的。

int* p1=new int;//配置設定一個int大小的空間 
int* p2=new int(3);//配置設定一塊空間,并将空間初始化成3. 
int* p3=new int[3];//配置設定3個int對象的空間。           

2、底層原理

其他記憶體管理接口 operator new/operator delete、operator new[]/operator delete[]

!!!operator …不是new/delete的重載!!!

總結:

operator new/operator delete、operator new[]/operator delete[]與malloc/free用法一樣。 

負責配置設定空間/釋放空間,但是不會調用構造函數和析構函數來初始化/清理對象。 

實際上operator new/operator delete是malloc/free的一層封裝。

new 做了兩件事 

  • 1. 調用operator new配置設定空間。 
  • 2. 調用構造函數初始化對象。

delete做了兩件事 

  • 1. 調用析構函數清理對象。 
  • 2. 調用operator delete釋放空間。

new [N] 

  • 1. 調用operator new配置設定空間。 
  • 2. 調用N此構造函數來初始化對象。

delete[N] 

  • 1. 調用N次析構函數清理對象。 
  • 2. 調用operator delete釋放空間。

問題來了?那麼數組底層是怎麼知道要調用N次析構函數的呢?

c中已經有了malloc和free,為什麼c++中會用new和delete?

(為了對象)簡單的說就是多開辟了四個位元組用來儲存調用了多少構造函數。

感覺抽象的話我們先看下這張圖,然後下來看下下面四種情況

c中已經有了malloc和free,為什麼c++中會用new和delete?
//(1)不會崩潰,雖然沒有調用析構函數 
AA* p0=new AA; 
free p0;
//(2)程式會崩潰,因為delete[]在對象使用完成後會預設将指針-4,取到最前面的位置調用析構函數,但是構造對象的時候是從目前位置開始的,是以就會出現指針越界,程式就會崩潰。 
AA* p1=new AA; 
delete[] p1;
//(3)程式會崩潰,free不會偏移4個位元組,釋放位置錯誤 
AA* p2=new AA[10]; 
free p2;
//(4)程式會崩潰,雖然delete隻析構一次,但是這不是程式崩潰的原因,主要原因是 釋放位置錯誤 
AA* p3=new AA[10]; 
delete p3;

//注AA為自定義類型
           

内置類型假如不比對也不會崩潰,是由于内置類型在開空間的時候不會多開四個位元組!!!