如何在编译器级别实现`delete [] obj`和`delete obj`

时间:2013-01-27 22:58:30

标签: c++ memory-management

  

可能重复:
  Why [] is used in delete ( delete [] ) to free dynamically allocated array?
  Why does C++ still have a delete[] AND a delete operator?

我想知道他们的区别是什么,我知道有人可能会说明显的答案,一个是删除一个数组,另一个是删除一个对象,但我想知道为什么要有两个不同的删除方法这两个行动?我的意思是删除基本上是使用C free方法实现的,它不关心指针是否实际指向数组或单个对象。我能想到的唯一原因是两个能够知道它是一个数组并且为每个单元调用析构函数而不是只调用第一个对象但是这也不可能,因为编译器无法猜测数组的长度只是看着它的指针。顺便说一下虽然据说调用未定义的行为来为delete分配的内存调用new[],我无法想象任何可能出错的事情。

3 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:1)

  

但由于编译器无法猜测,因此也不可能   数组的长度只是看着它的指针

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

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

答案 2 :(得分:0)

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

由于newdelete操作标量,他们不需要这样做,并且可以节省一点开销。

绝对不要求newdelete[]兼容,反之亦然。混合两者是不确定的行为。