2010-03-11 108 views
70

deletedelete[]運算符在C++中有什麼區別?刪除與刪除[] C++運算符

+0

你可能會發現這個問題相關http://stackoverflow.com/questions/1913343/how-could-pairing-new-with-delete-possibly-lead-to-memory-leak-only – sharptooth 2010-03-11 14:45:29

+4

與刪除和delete []是我喜歡智能指針的原因之一,並且只要我可以使用'vector <>'而不是數組。 – 2010-03-11 15:33:28

+0

http://stackoverflow.com/questions/1553382/pod-freeing-memory-is-delete-equal-to-delete – sbi 2011-01-12 16:05:08

回答

88

delete運算符取消分配內存並調用用new創建的單個對象的析構函數。

delete []運算符釋放內存並調用用new []創建的對象數組的析構函數。

在由new返回的指針上返回的指針new []delete []上使用delete會導致未定義的行爲。

+1

我不知道如果使用刪除一個新的[]原始類型的數組,如int或char(無構造函數/析構函數)也必然導致未定義的行爲。看起來,使用基元類型時,數組的大小並不存儲在任何地方。 – thomiel 2014-07-06 11:16:02

+12

如果標準沒有定義完成後會發生什麼,即使您的編譯器確定地執行了您希望的操作,它也是定義爲「未定義的行爲」。另一個編譯器可能會完全不同。 – 2014-12-23 15:24:24

+0

當我有一個像「char ** strArray」這樣的C字符串數組時,我犯了這個錯誤。如果你有像我這樣的數組,你需要遍歷數組並刪除/釋放每個元素,然後刪除/釋放strArray本身。使用「刪除[]」陣列我沒有工作,因爲(如上面的評論和回答指出),它呼叫DESTRUCTORS,它實際上並沒有釋放每個插槽。 – Katianie 2016-05-26 03:22:58

4

運營商deletedelete []分別用於銷燬用newnew[]創建的對象,返回到編譯器內存管理器可用的已分配內存。

使用new創建的對象必須使用delete銷燬,並且使用new[]創建的數組應該使用delete[]刪除。

75

delete[]運算符用於刪除數組。 delete運算符用於刪除非數組對象。它分別調用operator delete[]operator delete函數來刪除數組或非數組對象在(最終)調用數組元素或非數組對象的析構函數之後佔用的內存。

以下顯示了關係:

typedef int array_type[1]; 

// create and destroy a int[1] 
array_type *a = new array_type; 
delete [] a; 

// create and destroy an int 
int *b = new int; 
delete b; 

// create and destroy an int[1] 
int *c = new int[1]; 
delete[] c; 

// create and destroy an int[1][2] 
int (*d)[2] = new int[1][2]; 
delete [] d; 

對於new創建的陣列(這樣,無論是應用於陣列型構建體中的new type[]new),標準在該數組元素查找一個operator new[]類型類或全局作用域中,並傳遞請求的內存量。如果需要,它可能會請求超過N * sizeof(ElementType)(例如,要存儲元素的數量,所以在以後刪除時知道要完成多少析構函數調用)。如果這個類聲明瞭一個operator new[],那麼額外的內存容量可以接受另一個size_t,那麼第二個參數將會接收到分配的元素數 - 它可能會將它用於任何想要的目的(調試等等)。

對於創建非數組對象的new,它將在元素的類或全局範圍中查找operator new。它傳遞請求的內存量(總是sizeof(T))。

對於delete[],它查看數組的元素類類型並調用它們的析構函數。所使用的operator delete[]函數是元素類型的類中的函數,或者是全局範圍內沒有的函數。

對於delete,如果傳遞的指針是實際對象類型的基類,則基類必須具有虛擬析構函數(否則行爲未定義)。如果它不是基類,則調用該類的析構函數,並使用該類中的operator delete或全局operator delete。如果傳遞了基類,則調用實際的對象類型的析構函數,並使用該類中找到的operator delete,如果沒有,則調用全局的operator delete。如果該類中的operator delete具有size_t類型的第二個參數,它將接收要釋放的元素數量。

8

這基本使用分配/在C DE-分配格局++ 的malloc /免費,新/刪除,新的[] /刪除[]

我們需要相應地使用它們。但我想添加此特定的認識爲刪除之間的差和刪除[]

1)刪除用於分配用於單個對象

2)刪除解除分配存儲器[]用於解除分配存儲器分配用於陣列對象的

類ABC {}

ABC * PTR =新ABC [100]

,當我們說新的[100] ..編譯器可以瞭解有多少對象需要分配的信息(這裏是100),並調用構造每個對象的創建

,但相應地,如果我們簡單地用刪除PTR這種情況下,編譯器將不知道PTR指向並最終將調用析構函數和刪除記憶多少個對象只有1個對象(留下調用析構函數並釋放剩餘的99個對象)。因此會出現內存泄漏

所以我們需要在這種情況下使用delete [] ptr

+2

這應該是正確的答案。其他答案都沒有提到明顯的區別:「但是相應地,如果我們在這種情況下簡單地使用delete ptr,編譯器將不知道ptr指向多少個對象,並且最終只會調用析構函數並刪除只有一個對象的內存」 – 2015-06-14 01:22:15

+0

我們如何在C中實現同樣的事情? – 2017-04-28 19:10:42

-1

delete用於單個指針,delete[]用於通過指針刪除數組。 This可能會幫助你更好地理解。

0

當我問到這個問題時,我真正的問題是,「這兩者之間有什麼區別嗎?運行時不必保留關於數組大小的信息,所以也不能告訴我們哪一個意思?」這個問題沒有出現在「相關問題」中,所以只是爲了幫助像我這樣的人,這裏是答案:"why do we even need the delete[] operator?"

0

好吧..也許我認爲這只是爲了明確。 運算符刪除和運算符delete []區別但刪除運算符也可以釋放數組。

test* a = new test[100]; 
delete a; 

而且已經檢查過這個代碼沒有memeory泄漏。