使用delete
而不是delete[]
?有什么问题?
在分配和释放数组的过程中是否有一些特殊的事情发生?
为什么它会malloc
与免费不同?
创建的对象new[]
必须使用delete[]
.delete
在数组上使用未定义.
使用malloc和free,您可以获得更简单的情况.只有一个函数可以释放您分配的数据,也没有任何析构函数被调用的概念.混乱只是因为delete[]
和删除看起来相似.实际上它们是两个完全不同的功能.
使用delete不会调用正确的函数来删除内存.它应该调用delete[](void*)
,而是调用它delete(void*)
.因此,您不能依赖于使用delete
分配的内存new[]
请参阅此C++ FAQ
[16.13]我可以删除删除
[]
某些内置类型(char,int等)的数组吗?没有!
有时,程序员认为,
[]
在delete[] p
只存在这样编译器将调用适当的析构函数数组中的所有元素.由于这个推理,他们假设一些内置类型的数组,例如char
或者int
可以delete
没有[]
.例如,他们假设以下是有效代码:void userCode(int n) { char* p = new char[n]; ... delete p; // ? ERROR! Should be delete[] p ! }但上面的代码是错误的,它可能会在运行时导致灾难.特别是,所要求的代码
delete p
是operator delete(void*)
,但所需的代码delete[] p
是operator delete[](void*)
.后者的默认行为是调用前者,但允许用户用不同的行为替换后者(在这种情况下,他们通常也会替换运算符中的相应新代码new[](size_t)
).如果他们替换了delete[]
代码,因此它与删除代码不兼容,并且您调用了错误代码(即,如果您说delete p
而不是delete[] p
),则可能会在运行时遇到灾难.
为什么delete[]
首先存在?
无论你做x还是y:
char * x = new char[100]; char * y = new char;
两者都存储在char *
类型变量中.
我认为决定的原因delete
,以及delete[]
一系列支持C++效率的决策.这样就没有强制价格来查找正常删除操作需要删除多少.
拥有2 new
和new[]
似乎只有合乎逻辑的有delete
和delete[]
反正对称.
区别在于delete
只会删除整个内存范围,但只会为1个对象调用析构函数. delete[]
将删除内存并为每个对象调用析构函数.如果不使用delete[]
数组,那么在将资源泄漏引入应用程序之前只是时间问题.
编辑更新
根据标准,传递分配有new[]
to 的对象delete
是未定义的.在可能的行为是因为我描述它会采取行动.
关于原因,独立斯特劳斯会谈new
/ new[]
和delete/
通过10.5.1删除[]`运营商在部分10.3"的设计和C++的进化":
10.3数组分配 - 讨论了他们想要一种方法来允许使用与分配单个对象分开的单独方案来分配对象数组(即,从单独的存储分配数组).添加数组版本new
并delete
为此提供解决方案;
10.5.1解除分配数组 - 讨论如何仅使用单个delete
运算符解除分配数组的问题是,除了指针之外需要更多信息以确定指针是指向数组的第一个元素还是指向数组到一个对象.delete[]
运算符用于处理数组,而不是"使分配和解除分配单个对象的常见情况复杂化" .这符合一般的C++设计哲学"不要为你不使用的东西买单".
这个决定是否是一个错误是有争议的 - 无论哪种方式有充分的论据,但我们拥有我们拥有的.