为什么 delete[] 不等同于为 C++ 中的每个元素调用 delete?

Why is delete[] not equivalent to calling delete for each element in C++?

假设我在堆中创建了一个数组:

int* a = new int[10];

这是为什么:

for(int i = 0; i < 10; i++) {
        delete (a + i);
}

不等于delete[] a;?尝试为指向 a 中元素的任何指针调用 delete 会导致内存访问冲突。

具体有什么区别?

没有。数组类型存储相当于包含 one object ,为其分配了存储并且应该相应地释放它。

从 8.3.4 新

If the allocated type is a non-array type, the allocation function’s name is operator new and the deallocation function’s name is operator delete. If the allocated type is an array type, the allocation function’s name is operator new[] and the deallocation function’s name is operator delete[].

new 表达式返回的指针应由 delete 释放。 new[] 表达式 returns 指向数组第一个元素的指针和释放数组你应该只使用 delete[] 运算符。其他组合产生 UB,对数组元素使用 delete 是 UB。

您给 delete 的指针必须是 new 返回的指针。此外,如果您使用 new[] 分配对象,则必须使用 delete[] 删除它。

在许多实现中,保存有关分配信息的元数据(例如分配的大小)在分配之前存储在内存中。因此,当您将指针传递给 delete 时,它会在前面的内存位置中查找此信息。当您分配一个数组时,整个分配过程中只有这些元数据块之一。如果您尝试删除数组中的一个元素,它之前不会有任何元数据,因此它不知道要释放多少内存。

new int[10] 分配 一个 内存块,其空间足以容纳 10 个 int 类型的对象。当您完成该内存块时,您需要释放它;您使用 delete [] 执行此操作,它告诉运行时系统您已完成 one 内存块。

这是最简单的情况。当您为具有非平凡析构函数的类型分配内存时,编译器必须生成代码来销毁每个数组元素。在这种情况下,new T[10] 分配了 一个 内存块,其中有足够的空间容纳十个 T 类型的对象,并且它 创建 那十个对象使用了默认的构造函数。完成该内存块后,您需要释放它;你用 delete [] 来做到这一点,它为十个元素中的每一个调用析构函数,然后告诉运行时系统你已经完成了 one 内存块。