2009-10-13 97 views
7

我很困惑爲什麼下面的C++代碼可以編譯。爲什麼調用刪除0的方法不會產生任何錯誤?刪除NULL但沒有編譯錯誤

int *arr = NULL;  // or if I use 0, it's the same thing  
delete arr; 

我也嘗試運行它,它並沒有給我任何錯誤在所有...

+4

代碼不能編譯 - 你需要一個類型的指針(如void)而不僅僅是一個限定符;這不是(老)C. – 2009-10-13 04:16:39

回答

19

的C++語言擔保,刪除p不作什麼,如果p等於 NULL:此代碼應運行正常。

欲瞭解更多信息,請參閱第16.8,9 here

+0

不過,問題是爲什麼代碼*編譯*;不是爲什麼沒有運行時錯誤。 – Josh 2009-10-13 03:18:51

+5

在C++中刪除一個NULL指針是合法的,因此編譯器可以使用它。 – 2009-10-13 03:22:31

+0

解除引用null也合法嗎?如何溢出堆棧?向我展示一個編譯器,在這些條件下出錯...... – Josh 2009-10-13 03:25:39

0

NULL和0是不一樣的東西。在C++中,您應該使用0.

刪除空指針在語法上沒有任何錯誤或含糊不清。事實上,這在定義上是沒有用的;也就是說,刪除第0個地址的操作相當於什麼都不做。

+6

實際上,在C++中,NULL被定義爲0.此外,NULL與0是一個沒有明確答案的文體辯論。 – rlbond 2009-10-13 03:14:48

+2

絕對沒有理由在C++中優先選擇0而不是NULL。儘管出於某種原因,「C++中使用0」的建議不時出現。我不知道這個城市傳說的起源地,但是,再次,在C++中使用NULL絕對沒有錯,一般來說,爲了可讀性,NULL優於0。 – AnT 2009-10-13 03:30:10

+1

Stroustrup傾向於使用0而不使用NULL:http ://www.research.att.com/~bs/bs_faq2。html#null – ChrisW 2009-10-13 03:32:36

0

雖然您的示例很簡單,但編譯器無法知道(在編譯時)指針的值。

您也可以間接引用在編譯時零:

​​

編譯器沒有內置在編譯時處理這些類型的錯誤條件。

大多數(所有?)實現都將'delete 0'作爲非操作。雖然我不是100%肯定對:)

Object* pObject = new Object(); 
delete pObject; 
pObject = 0; 
delete pObject; 

+3

我不認爲刪除null是一個運行時錯誤。 – Jacob 2009-10-13 03:10:41

+0

你說得對。 雖然我遇到了雙刪除問題,或者我想象的是什麼? – Josh 2009-10-13 03:12:34

+4

任何C++編譯器都會將「delete NULL」視爲非空操作以外的任何東西,這是一種錯誤的編譯器。 C++語言指定刪除空指針是安全的。 (在相同的非NULL指針上調用delete兩次會使你陷入麻煩) – 2009-10-13 03:41:20

1

您可以刪除一個NULL指針沒有問題,你可能/可能有錯誤不會在編譯時間,但在運行時。

int *ptr_A = &a; 
ptr_A = NULL; 
delete ptr_A; 

通常是很方便的事情:

... 
delete ptr; 
ptr = NULL; 
+1

NULL指針通常是不好的做法。原因是指針應該封裝在類中。然後在析構函數中發生'delete',之後指針甚至不再存在,或者在賦值中不存在,其中指針獲得新值。因此,通常沒有方法將指針設置爲NULL。一個明顯的例外是不再需要的對象的「可選」部分,但考慮一下'boost :: optional '。 – MSalters 2009-10-13 09:44:09

1

,它在C和C++語言的事實標準(和他們不僅)是資源重新分配程序必須接受空指針參數和根本什麼都不做。實際上,這是一個相當常見的慣例。所以,真正的問題在這裏:它爲什麼會超越你?是什麼讓你覺得它會產生一個錯誤?此外,是什麼讓你認爲它應該不會編譯 ???

順便說一句,你的問題,它的陳述方式,似乎沒有多大意義,因爲你的代碼實際上不能編譯。假定的指針聲明缺少一個類型,這將使​​任何編譯器發出診斷消息。

+3

s/de-facto/de jure/- 請參閱ISO標準的引用。 – MSalters 2009-10-13 09:45:59

相關問題