2010-04-17 96 views
4

this page,它寫了我爲什麼要「刪除p;」,而不是「刪除(p + 1);」?爲什麼刪除需要左值?

一個原因是, 操作數刪除不需要是左值。 考慮:

delete p+1; 
delete f(x); 

這裏, 執行刪除沒有 的指針,它可以分配爲零。

給指針添加一個數字會將它在內存中向前移動很多數量的sizeof(*p)單位。

那麼,delete pdelete p+1之間的區別是什麼,以及爲什麼會使指針0僅與delete p+1有關?

+0

Strstroup建議C++編譯器設置指針,如果它是一個左值爲NULL。我個人認爲一些非空常量會更適合找到雙刪除錯誤,但即使如此... – Joshua 2010-04-17 02:33:34

+1

因爲加法的結果是一個右值,並且不能分配右值。同樣的原因,你不能說(1 + 1)= 4. – GManNickG 2010-04-17 02:34:40

+0

@GMan:怎麼樣'int * a = new int(10); *(a + 1)= 5;'那麼?這裏'p + 1'也是一個指針。 – Lazer 2010-04-17 02:38:59

回答

8

你不能這樣做p + 1 = 0。出於同樣的原因,如果你做delete p + 1然後刪除不能零操作數(p + 1),這是Stroustrup的FAQ的問題。

,你會永遠寫在delete p+1程序的可能性是相當低的,但是這不是重點...

+0

@Steve Jessop:因此,這與'p + 1'沒有分配'新的()'? – Lazer 2010-04-17 02:41:41

+1

在Stroustrup的上下文中使用它作爲FAQ問題的示例,沒有。在實踐中,如果'p + 1'產生的地址被賦予'new()',因爲'p'是從該地址中減去1得到的,那麼在標準C++中,'p'不是一個有效的指針,而且它實際上是未定義的行爲,即使添加1也是如此。不是你期望發現自己依賴的東西。所以這個例子不是現實的 - Michael Mrozek的'p-1'更好。我認爲Stroustrup只是選擇了「p + 1」作爲左值的一個例子,而不是你實際刪除的東西的一個例子。 – 2010-04-17 02:56:16

+0

「右值的例子」,我的意思是。哎呀。 – 2010-04-17 11:25:15

0

原因是,這些都不是左值,因此將它們設置爲NULL(或任何其他值)根本不可能。

+1

'f(x)'*可能是一個左值,它不一定是一個。 'f'可以返回'T *&'某種類型的T,在這種情況下,它是一個左值。或者它可以返回'T *',在這種情況下它是一個右值。 – 2010-04-17 02:31:27

5

p和p + 1指向不同的地方,因爲你正確地說sizeof(*p)單位相隔。您不能刪除尚未分配的內容,但例如:

A* p = new A(); 
p++; 
delete p-1; 

會刪除原始分配。當p + 1最初未分配時刪除p + 1是未定義的; glib翻轉出:

*** glibc detected *** free(): invalid pointer: 0x0804b009 *** 

由於p + 1不是要修改的變量,所以實現不能將p + 1歸零。該段說,

delete p; 

可以轉換爲

free(p); 
p = 0; 

這不會與p個感測+ 1

+0

你答案的第一部分是無關的 - 這與'p + 1'是否是一個有效的指針無關。重點是它不是左值。 – 2010-04-17 02:33:24

+1

什麼?他問了兩件事,第一件是「delete p和delete p + 1有什麼區別」 – 2010-04-17 02:37:37

+0

@Andrew Medico:是不是'lvalue',因爲我們沒有使用'new()'爲它分配內存,或者有一些完全不同的原因? – Lazer 2010-04-17 02:40:42

1

其實,你可以delete一個右值。規範中沒有任何內容(n3242)排除它。在實踐中,它gives no error

BTW,如果文章中說的刪除需要

操作數不是左值

這意味着它可能會,也可能不會是一個左值。它沒有說操作數不能是左值。