細說C (十七) new與delete解析(一)

2021-08-30 09:07:42 字數 2366 閱讀 6188

void

*operator new

(size_t)

;//allocate an object

void

*operator delete

(void*)

;//free an object

void

*operator new[

](size_t)

;//allocate an array

void

*operator delete(

void*)

;//free an array

(new和delete 為c++ 定義的關鍵字,通過特定的語法可以組成表示式)

底層解析

:舉例

class a~a

()private:

int var;

file *file;

};

,類 a 中有兩個私有成員,有乙個建構函式和乙個析構函式,建構函式中初始化私有變數 var 以及開啟乙個檔案,析構函式關閉開啟的檔案。

newclass a *pa = new a(10);

建立乙個類的物件,返回其指標 pa。如下圖所示 new 背後完成的工作:

new底層可解析為三步

(1)首先需要呼叫上面提到的 operator new 標準庫函式,傳入的引數為 class a 的大小,這裡為 8 個位元組,至於為什麼是 8 個位元組,你可以看看《深入 c++ 物件模型》一書,這裡不做多解釋。這樣函式返回的是分配記憶體的起始位址,這裡假設是 0x007da290。

(2)上面分配的記憶體是未初始化的,也是未型別化的,第二步就在這一塊原始的記憶體上對類物件進行初始化,呼叫的是相應的建構函式,這裡是呼叫 a:a(10); 這個函式,從圖中也可以看到對這塊申請的記憶體進行了初始化,var=10, file 指向開啟的檔案。

(3)最後一步就是返回新分配並構造好的物件的指標,這裡 pa 就指向 0x007da290 這塊記憶體,pa 的型別為類 a 物件的指標。

delete 底層分解兩步:

(1)呼叫 pa 指向物件的析構函式,對開啟的檔案進行關閉

(2)通過上面提到的標準庫函式 operator delete 來釋放該物件的記憶體,傳入函式的引數為 pa 的值,也就是 0x007d290

那麼 delete pa; 做了兩件事:

呼叫一次 pa指向的物件的析構函式;

呼叫 operator delete(pa); 釋放記憶體

string *psa = new string[10]

;//array of 10 empty strings

int*pia = new int[10

];//array of 10 uninitialized ints

delete [

] psa;

delete [

] pia;

注意:(new)上面在申請乙個陣列時都用到了 new 這個表示式來完成,按照我們上面講到的 new 和 delete 知識,

第乙個陣列是 string 型別,分配了儲存物件的記憶體空間之後,將呼叫 string 型別的預設建構函式依次初始化陣列中每個元素;

第二個是申請具有內建型別的陣列,分配了儲存 10 個 int 物件的記憶體空間,但並沒有初始化。

(delete)都用到 delete 表示式,注意這地方的 一般情況下不能漏掉!

我們也可以想象這兩個語句分別幹了什麼:第乙個對 10 個 string 物件分別呼叫析構函式,

然後再釋放掉為物件分配的所有記憶體空間;第二個因為是內建型別不存在析構函式,直接釋放為 10 個 int 型分配的所有記憶體空間。

注意兩點是:

(1)呼叫析構函式的次數是從陣列物件指標前面的 4 個位元組中取出;

(2)傳入 operator delete 函式的引數不是陣列物件的指標 paa,而是 paa 的值減 4。

C 之物件的new與delete

這裡單獨說一點對於類物件的new和delete中到底開闢的是哪段空間,釋放的是哪段空間。還是一樣舉個例子 class a a int main 構造器和析構器就不用說了,顯然構造器中的new是為str開闢了一段100位元組空間,析構器中delete釋放的也是為str的那100位元組大小的空間。那麼m...

c 中new與delete的過載

對於有一定程式設計基礎的人來說,new與delete一定會非常的熟悉,知道在使用的過程中 new 先分配memory 記憶體 再呼叫ctor 建構函式 而delete是先呼叫dtor 析構函式 再釋放memory。int p new int 10 int pa new int 10 new用來動態建...

C 中new與delete問題學習

一 new char與delete問題 1.問題程式 cpp view plaincopy include using namespace std void main 2.錯誤 當執行到delete時,程式出錯!3 解答 v1你用new申請了乙個char空間,把它的位址儲存在了des這個指標裡面 然...