【问题标题】:Why can I do "delete p;", but not "delete (p+1);"? Why does delete require an lvalue?为什么我可以“删除 p;”,但不能“删除 (p+1);”?为什么删除需要左值?
【发布时间】:2010-04-17 02:21:54
【问题描述】:

this page,上面写着

一个原因是 delete 不必是左值。 考虑:

delete p+1; 
delete f(x); 

这里, 执行删除没有 一个可以分配零的指针。

向指针添加一个数字会将其在内存中向前移动sizeof(*p) 的许多个单位。

那么,delete pdelete p+1 之间有什么区别,为什么将指针 0 设置为只有 delete p+1 的问题?

【问题讨论】:

  • Strstroup 建议 C++ 编译器将左值指针设置为 NULL。我个人认为一些非空常量更适合查找双重删除错误,但即便如此......
  • 因为加法的结果是右值,不能赋值。同样的原因你不能说 (1 + 1) = 4。
  • @GMan:那int *a = new int(10); *(a + 1) = 5; 呢?这里p+1 也是一个指针。
  • 这不是分配指针的目标(刚刚被释放),而是重定向指针本身。
  • 在您的代码中,a+1 是一个右值,但 *(a+1) 是一个左值,这就是您分配的值。 Stroustrup 正在谈论 delete 将指针归零,而不是指针。

标签: c++ pointers memory delete-operator


【解决方案1】:

你不能这样做p + 1 = 0。出于同样的原因,如果您执行delete p + 1,则 delete 无法将其操作数 (p+1) 清零,这就是 Stroustrup 的常见问题解答中的问题。

你曾经在程序中写过delete p+1 的可能性很低,但这不是重点......

【讨论】:

  • @Steve Jessop:所以,这与 p+1 没有使用 new() 分配无关?
  • 在 Stroustrup 的上下文中使用它作为该常见问题解答问题的示例,不。在实践中,如果p+1 导致分配了new() 的地址,因为p 是通过从该地址中减去1 获得的,那么在标准C++ 中,p 不是一个有效的指针,它实际上是未定义的行为甚至加 1。不是您期望发现自己依赖的东西。所以这个例子并不现实——Michael Mrozek 的p-1 更好。我认为 Stroustrup 只是选择了 p+1 作为左值的例子,而不是作为你实际删除的例子。
  • “右值示例”,我的意思是。哎呀。
【解决方案2】:

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' 是否是有效指针无关。关键是它不是左值。
  • 什么?他问了两件事,第一是“delete p和delete p+1有什么区别”
  • @Andrew Medico:这不是lvalue,因为我们没有使用new() 为其分配内存,还是出于完全不同的原因?
  • @eSKay 他们无关。左值是具有地址的值,因此可以出现在等式的左侧。 p 有一个地址,因为它是一个变量。 p+1 没有; p 指向的值与 1 相加,并且该临时值用于内联,但它不会永久存储在内存中的某处
【解决方案3】:

实际上,您可以 delete 一个右值。规范 (n3242) 中的任何内容都没有排除它。在实践中,它gives no error

顺便说一句,如果文章说

delete 的操作数不必是左值

这意味着它可能是左值,也可能不是左值。它并不是说操作数不能是左值。

【讨论】:

    【解决方案4】:

    原因是它们都不是左值,因此根本不可能将它们设置为 NULL(或任何其他值)。

    【讨论】:

    • f(x) 可能是一个左值,只是不一定是一个。 f 可以为某些类型 T 返回 T*&,在这种情况下它是一个左值。或者它可以返回T*,在这种情况下它是一个右值。
    猜你喜欢
    • 2018-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-12
    相关资源
    最近更新 更多