删除数组时,Delete和Delete[]是否相同

Delete and delete [] are the same when deleting arrays?

本文关键字:Delete 是否 数组 删除      更新时间:2023-10-16

可能的重复:
如何将new[]与delete配对可能只导致内存泄漏
(POD(释放内存:delete[]等于delete吗?

使用gcc版本4.1.2 20080704(Red Hat 4.1.2-48(。尚未在Visual C++上进行测试。

在删除"简单"类型的数组时,deletedelete []的工作原理似乎相同。

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!!!

我的问题是:

  1. 在第一个测试用例中,为什么deletedelete []在g++下相同
  2. 在第二个测试用例中,为什么g++不像第一个测试用例那样处理它

这一切都取决于底层内存管理器。简单地说,C++要求用delete[]删除数组,用delete删除非数组。你的行为标准中没有任何解释。

然而,可能发生的情况是,delete p;只是从p开始释放内存块(无论它是否是数组(。另一方面,delete[]额外地遍历数组的每个元素并调用析构函数。由于像char这样的普通数据类型没有析构函数,所以没有任何影响,所以deletedelete[]最终会做同样的事情。

正如我所说,这都是针对具体实施的。不能保证delete将在任何类型的数组上工作。这恰好适用于你的情况。在C++中,我们称之为未定义行为——它可能工作,也可能不工作,它可能会做一些完全随机和意外的事情。你最好避免依赖未定义的行为。

char * a = new char[1024];
delete a; // the incorrect way. also NO memory leak.

没有。它不符合No memory leak。它实际上调用了未定义的行为。

deletedelete[]在g++中看似等价纯属运气。在分配有new[]的内存上调用delete,反之亦然,这是未定义的行为。只是不要这么做。

因为这是未定义的行为。它不能保证会坏,但也不能保证能工作。

delete表达式在释放内存之前调用要删除的对象的析构函数。释放内存可能在任何一种情况下都有效(但它仍然是UB(,但如果在需要delete[]的地方使用delete,则不会调用所有的析构函数。由于复杂对象本身会分配内存,而内存又会在其自己的析构函数中释放,因此当使用错误的表达式时,无法进行所有这些删除。

它们在技术上并不相同,只是在非复杂类型上得到了相同的优化。复杂类型需要矢量化的delete,以便可以为数组中的每个对象调用析构函数delete(就像构造函数的矢量化new一样(。

你所做的只是释放内存,就像它是一个指针数组。

这里发生的情况是,当您调用delete时,对象占用的空间会被删除。在chars的情况下,这就是你所需要做的(尽管仍然建议使用delete[],因为这只是g++。在c++标准中,对数组调用delete的实际行为是未定义的。(

在第二个示例中,数组占用的空间被释放,包括指针m2。然而,m2所指向的内容并没有被删除。当您调用delete[]时,将调用数组中每个对象的析构函数,然后释放m2所指向的对象。