我偶尔会遇到这种代码 - 我怀疑创建者是/害怕表删除会迭代表和“性能表现”(imho不会以任何方式完成)...是可以从不使用表删除这里得到/考虑/想象的真正好处吗?
myClass** table = new myClass* [size];
... //some code that does not reallocate or change the value of the table pointer ;)
delete table; // no [] intentionally
答案 0 :(得分:19)
如果你这样做,你将得到C ++标准所谓的未定义行为 - 任何事情都可能发生。
答案 1 :(得分:8)
这是内存泄漏。 new []
必须与delete []
匹配。此外,由于table
是指向指针数组的第一个元素的指针,因此任何数组成员(如果它是一个数组本身)都需要使用delete []
取消分配。
答案 2 :(得分:8)
不仅没有任何好处,代码只是完全错误 - 充其量,它会泄漏内存,最糟糕的是,它可能会导致程序崩溃或打开难以找到的安全漏洞。您必须始终将new
与delete
和new[]
与delete[]
匹配。总是
答案 3 :(得分:5)
因为新的[]需要与delete []配对,这绝对是错误的。如果不这样做,您将得到未定义的行为。
它可能(部分)工作,因为大多数实现使用new来实现new []。这种实现的唯一区别是它只会调用1个析构函数(对于第一个元素而不是所有析构函数。但是要避免它,因为它不合法c ++ 。
答案 4 :(得分:4)
真的没有理由这样写,也没有理由不这样做。
对于具有普通析构函数的类型(在您的情况下类似于原始指针),确实无需知道数组中元素的实际数量,因此编译器可能决定映射 new [] 并删除[] 到 new 和 delete 以减少开销。如果它以这种方式决定你不能在没有采取额外步骤的情况下停止它,那么这个编译器优化将在没有你通知的情况下进行并且是免费的。
与此同时,有人使用您的代码可能希望重载全局运算符 new 和 delete (以及 new [] 和删除[] 。如果发生这种情况,您会遇到大麻烦,因为这可能是您真正需要 delete 和 delete [] 之间的区别。
此外,这种依赖于编译器的优化是不可移植的。
所以当你没有利用删除来取代 delete [] 这样的情况时会出现这种情况,但是很有可能依赖于未定义的行为。
答案 5 :(得分:2)
理论上你应该调用delete []。
编辑:以下内容仅适用于Microsoft Visual C ++ (我应该这样说)。
实际上,在Microsoft Visual C ++中,当数组中的对象没有析构函数时,使用哪个删除无关紧要。既然你有一个指针数组,并且指针不能有析构函数,你应该没问题。
然而,正如其他人所指出的那样,在没有[]的情况下混合new []和delete是不正确的C ++。虽然在这种情况下它可能在Visual C ++中工作,但代码不可移植,并且可能在其他编译器中失败。
但回到Visual C ++的特定情况,即使你调用delete [],编译器也会意识到当它是一个原始类型数组(如int,char)时,它不需要遍历调用析构函数的数组。或指针。在这种情况下调用删除实际上是有效的,不会破坏任何东西。做正确的事并调用delete []并不会慢,但它也不会更快。
实际上,在MSVC ++中,当p是指向简单类型的指针或没有析构函数的指针时,delete [] p会立即调用常规运算符delete(void * p)。
那些不相信我的人,将这段代码单步执行到前两次调用删除[]的CRT代码中。
#include "stdafx.h"
#include <malloc.h>
#include <iostream>
using namespace std;
class NoDestructor
{
int m_i;
};
class WithDestructor
{
public:
~WithDestructor()
{
cout << "deleted one WithDestructor at " << (void *) this<< endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
int **p = new int *[20];
delete [] p;
p = (int**) malloc(80);
free(p);
NoDestructor *pa = new NoDestructor[20];
delete [] pa;
WithDestructor *pb = new WithDestructor[20];
delete [] pb;
return 0;
}
答案 6 :(得分:1)
该语句将保留数组中所有指针所指向的所有myClass对象在内存中。它还将指针数组留在内存中。没有办法可以提供帮助,因为它只释放了32位内存,操作系统仍然认为你有(大小)myClasses和指向每个使用的指针。这只是一个程序员没有正确清理的例子。
答案 7 :(得分:1)
查看[16.11]部分“如何分配/取消分配一系列内容?”在C ++ FAQ Lite中,
http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.11
他们解释说,在创建数组时必须删除数组。
数组元素指向的myClass的实例也应该在创建它们的地方删除。