2010-02-24 73 views
4

刪除操作符如何工作?它是更好,然後免費()?另外如果你做ptr=new char[10],那麼使用delete ptr刪除,指針如何知道要刪除多少個位置。C++中的刪除操作如何知道要刪除多少內存位置

+4

我想你的意思是'delete'運算符。 – SLaks 2010-02-24 17:02:12

+12

你需要刪除[] ptr,否則你會遇到麻煩。 – 2010-02-24 17:03:28

+0

我冒昧地澄清你的頭銜,我希望你不要介意。另外,如果您想知道某個特定的編譯器和平臺,那麼包含它可能會很好。不同的編譯器可能有不同的方法來解決您所問的問題。 – Skurmedel 2010-02-24 17:04:11

回答

15

只有delete運營商,free只存在功能。在C++下,我們鼓勵您使用new/delete而不是malloc()/free()


在刪除操作符中有一個內部「魔術」。當使用new[]創建陣列時,陣列的大小將存儲在內存塊的元數據中。 delete[]使用該信息。

所有這些當然都是編譯器,操作系統,優化器和實現相關的。

+0

我建議將'new'更改爲'new []'並將'delete'更改爲'delete []'。 – fredoverflow 2010-02-24 17:15:22

+4

如果您錯誤地使用'delete ptr'而不是'delete [] ptr',那麼「魔術」可能會或可能不會正常工作,這又是非常依賴於實現的。 – 2010-02-24 17:16:43

+0

@FredOverflow,@Mark:的確,謝謝! – Vlad 2010-02-24 17:28:24

1

添加到@弗拉德的答案,如果你使用像運營商的新的[]的形式分配內存:

char *c = new char[10]; 

,那麼你必須使用相應的刪除形式:

delete[] c; 

你必須明確告訴編譯器在釋放期間使用元數據。

[編輯]

爲什麼你不能使用字符C []

因爲編譯器需要知道它需要預留在編譯時變量c大小。但是,使用新的[]表單會告訴它將分配推遲到運行時間。因此,編譯器錯誤。

+0

'char c [] = new char [10];'不編譯,你應該把'c []'改成'* c'。 – fredoverflow 2010-02-24 17:16:35

+0

該語句不合法,您不能更改字符數組的指針。我想你的意思是說char * c – shreyasva 2010-02-24 17:16:40

+0

感謝您指出錯誤。進行更正。 – ardsrk 2010-02-24 17:23:08

2
  1. 在C++中,使用new調用構造函數,但在使用malloc時不調用構造函數。同樣,使用delete時會調用析構函數,但在使用free時不會。

  2. 如果你有一個使用MyClass * x = new MyClass [25]的新數組,那麼你需要調用delete [] x,以便他們的系統知道它正在刪除(和破壞)一組對象而不是一個。

2

該實現計算出要銷燬的元素的數量(使用delete []時)。例如:

  • 新的char [10]可以分配一些額外的字節,將元素的數量放在開頭,然後返回指向第一個元素的指針。刪除[]然後可以在指針後面查看存儲的計數
  • 存儲相當於std :: map < void *,size_t >,並且新的T [n]將用返回的指針創建一個鍵,伯爵。刪除[]會在這個地圖上查找指針
  • 東西完全不同。它對你來說並不重要,只是它已經完成了(並且正如其他答案已經指出的那樣,使用delete []和new []!)
4

如果你做一個非數組類型:

T t = new T; 
// ... 
delete t; 

它會知道多少刪除,因爲它知道一件T有多大。如果你做一個數組:

T t* = new T[10]; 
// ... 
delete [] t; 

它會放下與分配一些額外的信息來告訴它多少刪除。請注意,我們使用delete [] t以及額外的[]來告訴它它是一個數組。如果你不這樣做,它會認爲它只是一個T,並且只釋放那麼多內存。

如果您使用newfree(如果使用malloc),請始終使用deletenew先分配內存,然後構造對象。同樣,delete調用析構函數,然後釋放內存。 malloc\free只處理內存分配和釋放。

2

這不是一個好壞的問題。兩者都是具有相同目標的操作,分配和釋放內存,但通常在C和C++的不同上下文中使用。此外,還有兩套操作之間的重要差別:

  • new/delete是C++的關鍵字,而不是C語言
  • new/delete是類型安全可用,而malloc()/free()是不。這意味着由malloc()free()返回的指針是void指針,需要將其轉換爲正確的類型。
  • new/delete隱式支持數組分配和使用該new[]delete[]語法使用由編譯器提供的元數據刪除,malloc()/free()不支持此語法
  • 施加new/delete一類型T將調用構造函數和分別的T析構函數,malloc()/free()不叫的T
  • malloc()的構造函數和析構函數會在內存耗盡的情況下返回NULLnew將拋出異常

請注意,爲防止內存損壞,應使用delete釋放使用new分配的內存。使用malloc()分配的內存也是如此,應該使用free()來釋放內存。

2

具體回答你的問題,刪除操作符調用析構函數,其中空閒不;因此您不想將malloc/free與new/delete混合使用。

當編譯器的庫從堆中獲取內存時,它會抓取的內容比您要求的要多一些,其中包括它的內部空間,一些元數據以及必要的填充。

說你malloc 128字節,或新的八個16字節大小的對象數組。編譯器實際上可能會抓取256個字節,在開始時包含一個小堆管理塊,記錄它給了你128個,但是抓取了256個,並且在它的頭之後的某個地方返回一個偏移量到256個塊中。你可以保證,從那個指針你有128個字節,你可以使用,但如果你超越了,你可能會遇到麻煩。

引擎蓋下的自由和刪除操作符將採用您交給的指針,備份已知的偏移量,讀取它的頭部塊,並知道將256個字節釋放回堆中。