做有什么区别:
int* I = new int[100];
for (int J = 0; J < 100; ++J)
{
delete I++;
}
//and
int* I = new int[100];
delete[] I;
我知道第一个是错误的。我知道如何正确使用 delete[] 与 delete。我只是想知道为什么这些有什么不同。就像在循环中找出 delete[] 和 delete 之间的真正区别一样。那么区别是什么呢?
做有什么区别:
int* I = new int[100];
for (int J = 0; J < 100; ++J)
{
delete I++;
}
//and
int* I = new int[100];
delete[] I;
我知道第一个是错误的。我知道如何正确使用 delete[] 与 delete。我只是想知道为什么这些有什么不同。就像在循环中找出 delete[] 和 delete 之间的真正区别一样。那么区别是什么呢?
new
和每个版本delete
都有两个任务:分配/释放和构造/销毁。
new
将分配内存并调用构造函数。
delete
将调用解构函数并释放内存。
new []
分配单个内存块,然后可能多次调用构造函数。
delete []
可能多次调用解构器,然后释放一块内存。
因此,delete
多次使用意味着释放多个内存块,而使用delete[]
将释放单个内存块;delete
多次使用不等于使用delete []
.
不同之处在于,首先,您要删除没有从new
.
没有可比性
delete
对所有new
s使用s
和delete []
s 代表所有new []
s
第一个只是删除不是来自的指针new
当您使用 时new Foo[n]
,您正在为一块足够大的内存进行一次分配,以容纳一组n
类型为 的连续元素Foo
。这与分配n
连续的内存块不同,每个Foo
.
从内存分配器的角度来看,它实际上只是一个大分配。当您执行delete array
ordelete (array + 42)
时,基本上会要求内存分配器删除包含特定项目的大分配部分,这是它无法做到的。这就像试图通过做来释放新对象的单个成员delete (&(new Foo())->bar)
- 对象的其余部分会发生什么?
即使在单元素数组上,delete array
也不会起作用,因为分配器对数组和单个对象使用不同的簿记逻辑(例如,存储数组中元素的数量)。所以你真的必须使用delete[]
withnew[]
和delete
with new
。
这是声明一个整数数组:
int* I = new int[100];
这是遍历整数数组并尝试删除它们:
for (int J = 0; J < 100; ++J)
{
delete I++; // bad
}
这是删除整数数组:
delete [] I; // correct
由于您使用 分配了数组[]
,因此您使用 取消分配它[]
。您不会取消分配分配给[]
without的内存[]
。
delete 和 delete[] 的区别在于 delete 将调用一个对象的析构函数,而 delete[] 将调用数组中每个对象的析构函数。在整数的情况下,差异并不明显,但如果你在析构函数中有任何影响,你会遇到问题,因为你不会正确地销毁所有对象。
也就是说,对于简单类型,您仍然不应该使用 delete 而不是 delete[],因为两个运算符的编译代码可能不同(例如,delete[] 可能期望将整数存储在与数组相邻的某个位置指示要删除的对象的数量)。所以,一般规则是如果你使用 new,总是使用 delete,如果你使用 new[],总是使用 delete[]。
第一个示例产生未定义的行为,因为纯删除表达式(与 delete[] 相对)只能应用于以下任一操作数:
对使用 new[] 分配的数组的单个元素调用 delete 不属于这些类别中的任何一个,因为数组的元素是非数组对象,它们不是用单独的 new 表达式创建的。
(C++ 标准 5.3.5)