C++中删除运算符的困惑

Confusion about delete operator in C++

这个问题看起来很简单,但是我的朋友和我争论说下面的程序调用了UB。但我认为他是不正确的。 考虑以下程序:

#include <iostream>
int main()
{
    int* p=new int[3]();
    int* q=p;
    for(int i=0;i<3;i++)
        std::cout<<q[i]<<' ';
    delete[] q;
    std::cout<<'\n';
}

这个程序的行为是否定义明确?如果我写 delete[] p; 而不是 delete[] q; 会发生什么?有效吗?

没有UB。它会工作正常。这里没什么可补充的。

是的,程序定义明确。首先,您创建一个分配给新分配内存的指针。

int* p=new int[3]();

然后你创建另一个指向那个内存的指针

int* q=p;

然后您使用该指针将数据分配到该内存中。之后你删除指向 q 的内存,它与 p 相同,没关系。程序returns一切顺利

delete 不关心你使用什么变量。重要的是指针指向的内存是用 new 创建的,并且您只在内存上调用一次 delete。

运算符 delete 只能应用于用运算符 new 分配的内存(即地址)。如果你分配一次你也应该释放(删除)一次,不使用哪个指针(变量存储地址),所以你的代码是有效的。

但是,请记住,在您 delete[] q 之后,qp 都不必使用。最好的方法是将 NULL 分配给两个指针。

new[] 运算符返回的指针不是分配内存的开始,而是指向第一个对象(或索引 0 处的对象)。现在,based on the compiler you're using,运行-time 系统将对象的数量 n 存储在某个地方,如果您只知道 p.[=18= 指向的内存位置,就可以检索到它。 ]

According to this blog,一个vector的删除反过来执行这个操作:

When you do "delete[] p", you are saying, "p points to a bunch of objects, but I'm not telling you how many." In this case, the compiler needs to generate extra code to keep track of how many it needs to destruct. This extra information is kept in a "secret place" when the vector is allocated with "new[]".

因为 int *q = p 本质上指向同一个数组的第 0 个对象,所以相当于调用 delete[] qdelete[] p.