在this page,它写了我为什么要“删除p;”,而不是“删除(p + 1);”?为什么删除需要左值?
一个原因是, 操作数删除不需要是左值。 考虑:
delete p+1;
delete f(x);
这里, 执行删除没有 的指针,它可以分配为零。
给指针添加一个数字会将它在内存中向前移动很多数量的sizeof(*p)
单位。
那么,delete p
和delete p+1
之间的区别是什么,以及为什么会使指针0
仅与delete p+1
有关?
在this page,它写了我为什么要“删除p;”,而不是“删除(p + 1);”?为什么删除需要左值?
一个原因是, 操作数删除不需要是左值。 考虑:
delete p+1;
delete f(x);
这里, 执行删除没有 的指针,它可以分配为零。
给指针添加一个数字会将它在内存中向前移动很多数量的sizeof(*p)
单位。
那么,delete p
和delete p+1
之间的区别是什么,以及为什么会使指针0
仅与delete p+1
有关?
你不能这样做p + 1 = 0
。出于同样的原因,如果你做delete p + 1
然后删除不能零操作数(p + 1),这是Stroustrup的FAQ的问题。
,你会永远写在delete p+1
程序的可能性是相当低的,但是这不是重点...
@Steve Jessop:因此,这与'p + 1'没有分配'新的()'? – Lazer 2010-04-17 02:41:41
在Stroustrup的上下文中使用它作为FAQ问题的示例,没有。在实践中,如果'p + 1'产生的地址被赋予'new()',因为'p'是从该地址中减去1得到的,那么在标准C++中,'p'不是一个有效的指针,而且它实际上是未定义的行为,即使添加1也是如此。不是你期望发现自己依赖的东西。所以这个例子不是现实的 - Michael Mrozek的'p-1'更好。我认为Stroustrup只是选择了“p + 1”作为左值的一个例子,而不是你实际删除的东西的一个例子。 – 2010-04-17 02:56:16
“右值的例子”,我的意思是。哎呀。 – 2010-04-17 11:25:15
原因是,这些都不是左值,因此将它们设置为NULL(或任何其他值)根本不可能。
'f(x)'*可能是一个左值,它不一定是一个。 'f'可以返回'T *&'某种类型的T,在这种情况下,它是一个左值。或者它可以返回'T *',在这种情况下它是一个右值。 – 2010-04-17 02:31:27
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
你答案的第一部分是无关的 - 这与'p + 1'是否是一个有效的指针无关。重点是它不是左值。 – 2010-04-17 02:33:24
什么?他问了两件事,第一件是“delete p和delete p + 1有什么区别” – 2010-04-17 02:37:37
@Andrew Medico:是不是'lvalue',因为我们没有使用'new()'为它分配内存,或者有一些完全不同的原因? – Lazer 2010-04-17 02:40:42
其实,你可以delete
一个右值。规范中没有任何内容(n3242)排除它。在实践中,它gives no error。
BTW,如果文章中说的删除需要
操作数不是左值
这意味着它可能会,也可能不会是一个左值。它没有说操作数不能是左值。
Strstroup建议C++编译器设置指针,如果它是一个左值为NULL。我个人认为一些非空常量会更适合找到双删除错误,但即使如此... – Joshua 2010-04-17 02:33:34
因为加法的结果是一个右值,并且不能分配右值。同样的原因,你不能说(1 + 1)= 4. – GManNickG 2010-04-17 02:34:40
@GMan:怎么样'int * a = new int(10); *(a + 1)= 5;'那么?这里'p + 1'也是一个指针。 – Lazer 2010-04-17 02:38:59