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

时间:2018-05-05 09:43:54

标签: c++ delete-operator

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

next(m['result'] for m in L if m['name'] == 'sara')

为什么:

int* a = new int[10];

不等同于for(int i = 0; i < 10; i++) { delete (a + i); } ?试图调用delete[] a;指向delete中任何元素的指针会导致内存访问冲突。

差别究竟是什么?

3 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:2)

没有。数组类型存储相当于包含一个对象,为其分配了存储空间,因此应该对其进行解除分配。

从8.3.4新

  

如果分配的类型是非数组类型,则为分配函数   name是operator new,deallocation函数的名称是operator   删除。如果分配的类型是数组类型,则分配   函数的名称是operator new []和deallocation函数的名称   是operator delete []。

new表达式返回的指针应该通过delete取消分配。 new[]表达式返回指向数组第一个元素的指针,并且要解除分配数组,您应该只使用delete[]运算符。其他组合产生UB,并且对数组元素的使用删除是UB。

答案 2 :(得分:0)

new int[10]分配一个内存块,为10个int类型的对象留出足够的空间。当你完成那个内存块后,你需要释放它;你使用delete []执行此操作,它告诉运行时系统您已完成一个内存块。

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