4

可能重复:
为什么在 delete ( delete [] ) 中使用 [] 来释放动态分配的数组?
为什么 C++ 仍然有一个 delete[] AND 一个删除运算符?

我想知道它们有什么区别,我知道有些人可能会说的明显答案,一个是删除数组,另一个是删除单个对象,但我想知道为什么这两个操作应该有两种不同的删除方法? 我的意思是删除基本上是使用 Cfree方法实现的,它不关心指针实际上是指向数组还是单个对象。我能想到的唯一原因是两个能够知道它是否是一个数组并为每个单元格调用析构函数,而不仅仅是第一个对象,但这也是不可能的,因为编译器无法猜测数组的长度只是看着它指针。顺便说一句,虽然据说调用未定义的行为来调用delete分配的内存new[]我可以'

4

3 回答 3

3

正如您所发现的,编译器需要知道数组的长度(至少对于非平凡类型)才能为每个元素调用析构函数。对于这个 new[] 通常分配一些额外的字节来记录元素计数并返回一个指向这个簿记区域末尾的指针。

当您使用 delete[] 时,编译器将查看数组之前的内存以找到计数并调整指针,以便释放最初分配的块。

如果您用于delete销毁动态分配的数组,则不会调用元素(第一个除外)的析构函数,通常这将最终尝试释放不指向已分配块开头的指针,这可能会损坏堆。

于 2013-01-27T23:06:44.233 回答
1

但这也是不可能的,因为编译器不能仅仅看它的指针就猜出数组的长度

这不是真的。编译器本身不需要猜测任何东西,但它会根据它看到的运算符决定调用哪个函数来释放内存。有一个单独的函数专门用于释放数组,并且该函数确实知道要释放的数组的长度,因此它可以适当地调用析构函数。

它知道数组的长度,因为通常new[]分配的内存包括数组长度(因为这在分配时是已知的)并返回一个指向仅分配的“可用”内存的指针。当delete[]被调用时,它知道如何根据指向给定数组可用部分的指针来访问该内存。

于 2013-01-27T23:01:16.920 回答
0

当您使用 分配内存new[]时,编译器不仅需要构造每个元素,还需要跟踪已分配的元素数量。delete[]这是正常工作所必需的。

由于newdelete对标量进行操作,因此它们不需要这样做,并且可以节省一点开销。

绝对不需要new兼容,delete[]反之亦然。将两者混合是未定义的行为。

于 2013-01-27T23:01:31.573 回答