2010-04-17 65 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,如果文章中说的删除需要

操作数不是左值

这意味着它可能会,也可能不会是一个左值。它没有说操作数不能是左值。