删除[]与删除在for循环中

delete[] vs delete in a for loop

本文关键字:删除 循环 for      更新时间:2023-10-16

做以下操作有什么区别:

int* I = new int[100];
for (int J = 0; J < 100; ++J)
{
    delete I++;
}
//and
int* I = new int[100];
delete[] I;

我知道第一个是错误的。我知道如何正确使用删除[]与删除。我只想知道为什么这些有什么不同。就像在循环中找出 delete[] 和 delete 之间的真正区别一样。那么有什么区别呢?

newdelete的两个版本都有两个任务:分配/释放和构造/销毁。

  • new将分配内存并调用构造函数。

  • delete将调用解构函数并释放内存。

  • new []分配单个内存块,然后可能多次调用构造函数。

  • delete []可能会多次调用解构函数,然后解除分配单个内存块。

因此,多次使用 delete 意味着解除分配多个内存块,而使用 delete[] 将释放单个内存块;多次使用 delete 并不等同于使用 delete []

不同之处在于,首先,您要删除未从new返回的指针。

没有比较的意义

对所有new使用 delete s

delete [] s 适用于所有new []

第一个只是删除不是来自new的指针

当你使用 new Foo[n] 时,你正在为一个足够大的内存块进行一次分配,以容纳一个 Foo 类型的n连续元素数组。这与分配n连续的内存块不同,每个内存块Foo一个。

从内存分配器的角度来看,它实际上只是一个大的分配。当你执行delete arraydelete (array + 42)时,内存分配器基本上被要求删除包含特定项目的大分配部分,这是它无法做到的。这就像试图通过执行delete (&(new Foo())->bar)来释放新对象的单个成员 - 对象的其余部分会发生什么?

即使在单元素数组上,delete array也不会起作用,因为分配器对数组和单个对象使用不同的簿记逻辑(例如,存储数组中的元素数)。因此,您确实必须将delete[]new[]一起使用,deletenew一起使用。

这是

声明一个整数数组:

int* I = new int[100];

这是遍历整数数组并尝试删除它们:

for (int J = 0; J < 100; ++J)
{
    delete I++; // bad
}

这是删除整数数组:

delete [] I; // correct

由于您使用 [] 分配了数组,因此使用 [] 解除分配它。 您不会在没有 [] 的情况下解除分配[]的内存。

delete 和 delete[]

之间的区别在于,删除将调用一个对象的析构函数,而 delete[] 将调用数组中每个对象的析构函数。在 ints 的情况下,差异并不明显,但是如果你在析构函数中有任何后果,你会有问题,因为你不会正确地破坏所有对象。

也就是说,对于简单类型,您仍然不应该使用 delete 而不是 delete[],因为编译的代码对于两个运算符可能不同(例如,delete[] 可能期望将整数存储在数组旁边的某个位置以指示要删除的对象数)。因此,一般规则是,如果您使用 new,请始终使用 delete,如果您使用 new[],请始终使用 delete[]。

第一个示例产生未定义的行为,因为纯删除表达式(与 delete[] 相反)只能应用于以下操作数:

  • 空指针值
  • 指向由上一个新表达式创建的非数组对象的指针
  • 或指向子对象的指针

对分配了 new[] 的数组的单个元素调用 delete 不属于这两个类别中的任何一个,因为数组的元素是非数组对象,尚未使用单个新表达式创建。

(C++标准 5.3.5)