C++中的delete运算符及其内存位置

3

我是C++的新手,现在正在学习newdelete关键字。

Point ppaa = *new Point;
Point *p = &ppaa;

ppaa.xpos = 1;
ppaa.ypos= 3;

delete &ppaa;
delete p;

请问为什么我无法使用&ppaa删除上面的ppaa?我知道delete只能操作指针,但我不明白为什么这样做不行,因为它们实际上是内存位置。搜索类似的问题,似乎与第一行发生的复制操作有关,但我没有很好的解释。


你的内存泄漏了。这个链接可能会有所帮助:https://dev59.com/t2ox5IYBdhLWcg3w_ZR0#8840302 - Pubby
谢谢Pubbu,它帮了我很多。您能否请查看Als答案下发布的附加问题? - noclew
1个回答

3
 T t = x;

被称为复制初始化。它的执行步骤如下:

  • x转换为类型T的对象;
  • 将该对象复制到要初始化的对象t中。

因此,您的代码语句为:

Point ppaa = *new Point;
  • 创建一个freestore/heap上的Point对象,
  • 然后复制该对象以创建堆栈对象ppaa

这两个对象是不同的对象。
正如您所看到的,执行此语句后,您不再拥有对堆对象的任何指针。
在这种情况下,您需要将new返回的地址传递给delete,因为您不再拥有该地址,它会导致内存泄漏。
此外,请注意,&ppaa不返回new返回的地址,它返回位于堆栈上的对象ppaa的地址。将此地址传递给delete会导致未定义行为,因为ppaa从未在freestore/dynamically上分配,而是基于堆栈的本地/自动对象。


非常感谢您的详细解释。现在我可以看到我的代码是如何工作的了!我已经使用C#有一段时间了,所以这个复制初始化对我来说非常有趣。只是为了明确,如果我在C#中写成这样(而不是在C++中):T t1 = new T(); T t2 = t1; 那么t2只是t1的一个引用,在C++中没有像复制过程那样的操作。我是正确的吗? - noclew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接