首頁 > 軟體

C++超詳細探究new/delete的使用

2022-07-01 14:03:44

記憶體管理

在C++中,一個可執行程式的虛擬地址空間可分為,核心、棧、共用庫的記憶體對映區域、堆、資料區和程式碼段,具體分佈額如下圖所示:

核心: 作業系統

棧區: 函數的形參,非靜態的區域性變數,函數現場保護資料等等,棧是向下增長的。

共用庫的記憶體對映區域 用於裝載一個共用的動態記憶體庫。使用者可使用系統介面建立共用記憶體,做程序間通訊。

堆區: 用於程式執行時動態記憶體分配,堆是可以上增長的。

資料段: 儲存全域性資料和靜態資料,分為.bss 和.data 。

程式碼段: 可執行的程式(機器指令)和 常數資料。

C的動態記憶體管理:

new/delete

在C++中 ,關於動態記憶體的申請,依靠關鍵字new來實現,new在有三種用法:

1.new運運算元的使用

範例如下:

int n = 10;
int *ipa = new int (10); 
int *ipb = new int [n](10);
int *ipc = new int[n]{1,2,3,4,5,6,7,8};

在這裡new主要做了三個操作,

  • 申請一個空間
  • 在申請的空間中構造一個int 的物件,並將該物件返回到空間中
  • 將空間的地址返回

在上述的程式碼中,我們可以開闢一個空間如 ipa 所示;我們也可以開闢一組空間如ipb所示;我們也可以開闢一組空間的同時給所有或者部分元素給定初始值如ipc所示。

當然,動態記憶體的開闢後,需要我們去手動去釋放它,在C++ 中,我們通過delete來釋放記憶體,如下所示

delete ipa;
delete[]ipb;
delete[]ipc;

如上程式碼所示,當我們開闢一個空間時,我們可以直接通過其地址釋放,當我們申請一組空間時,我們需要加上**[]**,需要告訴編譯器,我們要釋放一組記憶體。

注: 當我們釋放一組記憶體時,我們不需要在[]裡面寫入需要釋放的動態記憶體的數目,原因是當我們通過new去申請一組動態記憶體時,編譯器會自動開闢空間去儲存new開闢的空間的數目大小,當我們使用delete 來釋放空間時,編譯器會自動去存取這個空間來檢視開闢的記憶體大小數目。

2.new的函數方法的使用

new當作函數使用時,其功能和malloc及其相似,唯一不同的地方在與 當申請記憶體失敗時,malloc會返回NULL,因此,我們在每次使用malloc時候必須對指標進行判空;但是new申請記憶體失敗後是丟擲異常,所以需要捕獲例外處理程式;

範例如下:

int n = 10;
int *ipa = (int*)::operator new(sizeof(int));
// 			     (int*)malloc(sizeof(int));
int *ipb = (int*)::operator new(sizeof(int)*n);
// 				  (int*)malloc(sizeof(int)*n);

當然,我們也需要delete去釋放其空間

 delete(ipa);
 delete(ipb);

3.定位new

定位new的用法主要是,它不會去自己開闢空間,而是一塊已知的記憶體上分配給一個物件,但是記憶體上的資料不會被覆蓋或者改寫,其程式碼範例如下:

int n = 10;
int* ipa = (int*)malloc(sizeof(int));
int* ipb = (int*)::operator new(sizeof(int) * n);
new(ipa) int(20);
new(ipb) int[]{ 1,2,3,4,5,6,7,8,9 };

並且 ,通過定位new的方法去把已經申請的存在的記憶體分配的方法,它可以去分配堆裡面的記憶體,也可以去分配棧裡面的記憶體;定位new的方法也可以將原本申請為int型別的記憶體看成char/double來顯示。

注: 關於C++的內建型別 int/double/char 等等 ,並不是編譯器將其劃分,而是使用者自身,當我們把資料按照4個位元組當一個整體來看待,那麼其就是整型,若是按照一個位元組為一個單位,那就是char型別;若是8個位元組看成一個單位,那就是double型別。而資料在記憶體儲存的值並不會發生任何改變。

new/delete/malloc/free區別

1、new/delete 是C++中的運運算元。 malloc / free 是函數。

2、 malloc申請記憶體空間時,手動計算所需大小,new只需型別名,自動計算大小;

3、 malloc申請的記憶體空間不會初始化,new可以初始化;

4、 malloc的返回值為void*, 接收時必須強轉,new不需要;

5、 malloc申請記憶體空間失敗時,返回的是NULL,使用時必須判空;

new申請記憶體空間失敗時丟擲異常,所以要有捕獲例外處理程式;

到此這篇關於C++超詳細探究new/delete的使用的文章就介紹到這了,更多相關C++ new/delete內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com