可能重复:
How could pairing new[] with delete possibly lead to memory leak only?
( POD )freeing memory : is delete[] equal to delete?
使用gcc版本4.1.2 20080704(Red Hat 4.1.2-48)。尚未在Visual C ++上进行测试。
删除“简单”类型的数组似乎delete
和delete []
的工作方式相同。
char * a = new char[1024];
delete [] a; // the correct way. no memory leak.
char * a = new char[1024];
delete a; // the incorrect way. also NO memory leak.
但是,当删除“复杂”类型的数组时,delete
将导致内存泄漏。
class A
{
public:
int m1;
int* m2; // a pointer!
A()
{
m2 = new int[1024];
}
~A()
{
delete [] m2; // destructor won't be called when using delete
}
};
A* a = new A[1024];
delete [] a; // the correct way. no memory leak.
A* a = new A[1024];
delete a; // the incorrect way. MEMORY LEAK!!!
我的问题是:
delete
和delete []
在g ++下是相同的?答案 0 :(得分:9)
这完全取决于底层内存管理器。简而言之,C ++要求您删除带有delete[]
的数组,并删除带有delete
的非数组。标准中没有解释您的行为。
然而,可能发生的事情是delete p;
只是从p
开始释放内存块(无论是否是数组)。另一方面,delete[]
另外运行数组的每个元素并调用析构函数。由于像char
这样的普通数据类型没有析构函数,因此没有效果,因此delete
和delete[]
最终会做同样的事情。
就像我说的,这是所有特定的实现。无法保证delete
可以在任何类型的数组上运行。它恰好适用于您的情况。在C ++中,我们称之为未定义的行为 - 它可能起作用,它可能不起作用,它可能会做一些完全随机和意外的事情。你最好避免依赖未定义的行为。
答案 1 :(得分:6)
char * a = new char[1024];
delete a; // the incorrect way. also NO memory leak.
没有。它没有保证No memory leak
。它实际上调用了未定义的行为。
答案 2 :(得分:3)
delete
和delete[]
看起来在g ++中是等价的,纯粹是运气。在分配有delete
的内存上调用new[]
,反之亦然,是未定义的行为。只是不要这样做。
答案 3 :(得分:1)
因为那是未定义的行为。它不能保证会中断,但也不保证能够正常工作。
答案 4 :(得分:1)
delete 表达式在释放内存之前调用要删除的对象的析构函数。释放内存可能适用于任何一种情况(但它仍然是UB),但是如果你在需要delete
的地方使用delete[]
,那么你就不会调用所有的析构函数。由于您的复杂对象本身会分配内存,而内存又在其自己的析构函数中释放,因此当您使用错误的表达式时,您无法进行所有这些删除。
答案 5 :(得分:0)
delete
,以便可以为数组delete
中的每个对象调用析构函数(就像构造函数的向量化new
一样)。
你做的只是自由的内存就像它的指针数组一样。
答案 6 :(得分:0)
这里发生的是当您调用delete时,将删除对象占用的空间。在chars的情况下,这就是你需要做的所有事情(尽管仍然建议使用delete [],因为这只是g ++。在c ++标准中,在数组上调用delete的实际行为是未定义的。)。
在第二个示例中,释放了数组占用的空间,包括指针m2。但是,m2指向的内容也不会被删除。当你调用delete []时,会调用数组中每个对象的析构函数,然后释放m2指向的内容。