delete 和 delete 的真正區別

2021-09-19 12:56:55 字數 2682 閱讀 8689

c++中對new申請的記憶體的釋放方式有delete和delete[兩種方式,到底這兩者有什麼區別呢?

1.我們通常從教科書上看到這樣的說明:

delete 釋放new分配的單個物件指標指向的記憶體

delete 釋放new分配的物件陣列指標指向的記憶體

那麼,按照教科書的理解,我們看下下面的**:

int *a = new int[10];

delete a;        //方式1

delete a;     //方式2

肯定會有很多人說方式1肯定存在記憶體洩漏,是這樣嗎?

(1). 針對簡單型別 使用new分配後的不管是陣列還是非陣列形式記憶體空間用兩種方式均可 如:

int *a = new int[10];

delete a;

delete a;

此種情況中的釋放效果相同,原因在於:分配簡單型別記憶體時,記憶體大小已經確定,系統可以記憶並且進行管理,在析構時,系統並不會呼叫析構函式,

它直接通過指標可以獲取實際分配的記憶體空間,哪怕是乙個陣列記憶體空間(在分配過程中 系統會記錄分配記憶體的大小等資訊,此資訊儲存在結構體_crtmemblockheader中,

具體情況可參看vc安裝目錄下crt\src\dbgdel.cpp)

(2). 針對類class,兩種方式體現出具體差異 

當你通過下列方式分配乙個類物件陣列:

class a

~a()

};a *a = new a[10];

delete a;//僅釋放了a指標指向的全部記憶體空間 但是只呼叫了a[0]物件的析構函式 剩下的從a[1]到a[9]這9個使用者自行分配的m_cbuffer對應記憶體空間將不能釋放從而造成記憶體洩漏

delete a;      //呼叫使用類物件的析構函式釋放使用者自己分配記憶體空間並且   釋放了a指標指向的全部記憶體空間

所以總結下就是,如果ptr代表乙個用new申請的記憶體返回的記憶體空間位址,即所謂的指標,那麼:

delete   ptr   代表用來釋放記憶體,且只用來釋放ptr指向的記憶體。 

delete   rg   用來釋放rg指向的記憶體,!!還逐一呼叫陣列中每個物件的destructor!!

對於像int/char/long/int*/struct等等簡單資料型別,由於物件沒有destructor,所以用delete 和delete 是一樣的!但是如果是c++物件陣列就不同了!

關於 new 和 delete,其中又分為兩種情況:(1) 為基本資料型別分配和**空間;(2) 為自定義型別分配和**空間。 

對於 (1),上面提供的程式已經證明了 delete 和 delete 是等同的。但是對於 (2),情況就發生了變化。

我們來看下面的例子,通過例子的學習了解c++中的delete和delete的使用方法

#include

using namespace std;

/class babe

class babe

~babe()

};//main function

int main()

結果是:

create a babe to talk with me

create a babe to talk with me

create a babe to talk with me

babe don\'t go away,listen to me

create a babe to talk with me

create a babe to talk with me

create a babe to talk with me

babe don\'t go away,listen to me

babe don\'t go away,listen to me

babe don\'t go away,listen to me

大家都看到了,只使用delete的時候只出現乙個 babe don\'t go away,listen to me,而使用delete的時候出現3個 babe don\'t go away,listen to me。不過不管使用delete還是delete那三個物件的在記憶體中都被刪除,既儲存位置都標記為可寫,但是使用delete的時候只呼叫了pbabe[0]的析構函式,而使用了delete則呼叫了3個babe物件的析構函式。你一定會問,反正不管怎樣都是把儲存空間釋放了,有什麼區別。答:關鍵在於呼叫析構函式上。此程式的類沒有使用作業系統的系統資源(比如:socket、file、thread等),所以不會造成明顯惡果。如果你的類使用了作業系統資源,單純把類的物件從記憶體中刪除是不妥當的,因為沒有呼叫物件的析構函式會導致系統資源不被釋放,如果是socket則會造成socket資源不被釋放,最明顯的就是埠號不被釋放,系統最大的埠號是65535(216 _ 1,因為還有0),如果埠號被占用了,你就不能上網了,呵呵。如果file資源不被釋放,你就永遠不能修改這個檔案,甚至不能讀這個檔案(除非登出或重器系統)。如果執行緒不被釋放,這它總在後台執行,浪費記憶體和cpu資源。這些資源的釋放必須依靠這些類的析構函式。所以,在用這些類生成物件陣列的時候,用delete來釋放它們才是王道。而用delete來釋放也許不會出問題,也許後果很嚴重,具體要看類的**了.

delete和delete 的區別

剛才在寫一段例子程式的時候,發現對於乙個指標型別的陣列t p,delete p和delete p的效果一樣。看了一下c primer和c programming language都沒有找到解釋,於是在網路上搜尋一下,發現了很好的解釋。整理一下 c 告訴我們在 用 new 分配的單個物件的記憶體空間的...

delete和delete 的區別

c 告訴我們在 用 new 分配的單個物件的記憶體空間的時候用 delete,用 new 分配的一組物件的記憶體空間的時候用 delete。樓主的這個問題提得很好。很多人注意到了這個問題,但是卻不清楚為什麼要這樣做,不這樣做行不行。關於 new 和 delete,其中又分為兩種情況 1 為基本資料型...

delete 和 delete 的區別

情景 今天在檢視別人寫的 時發現有類似如下 printer info 4 info4 printer info 4是乙個普通的結構 即沒寫構造和析構等函式的純資料的struct info4 printer info 4 new byte dwneeded delete info4 好奇這一句的寫法,...