在类的析构函数中删除数组

Posted

技术标签:

【中文标题】在类的析构函数中删除数组【英文标题】:Deleting array in destructor of the class 【发布时间】:2014-11-21 00:29:09 【问题描述】:

我有类 NameClass 成员:

class NameClass 
    public:

    int count;
    apple* array;
 

及其构造函数:

NameClass::NameClass()

    count = 12;
    array = new apple[count];
    ...

我应该在类的析构函数中删除这个数组吗?如何?

这会导致错误(“被释放的指针未被分配”):

delete []apple;
or 
delete apple;

【问题讨论】:

@chris 你知道这是作业。 delete []array; 是正确的(delete []apple; 没有意义,不应该编译,如果苹果是一个类,如代码所示)。如果您仍然收到错误,则您在此处显示的特定构造函数未执行或 array 在对象的生命周期内被设置为其他值。也许,还有另一个分配数组的构造函数?也许,你有一个不做深拷贝的拷贝构造函数/拷贝赋值运算符,所以你要删除数组两次(在两个对象中)?我们只能猜测...... @Oguk,构造函数只有一个,没有运算符。 @mostruash “你知道这是功课。”我们通常不在乎,除非 OP 正确地明确说明了他们的要求和限制。 你还需要遵守三法则。 【参考方案1】:

delete []array; 应该是析构函数中使用的正确删除操作。

如果您收到上述错误

“这会产生错误(“被释放的指针没有被分配”):“

您要么错过了使用nullptr(或NULL)正确初始化array,要么将未分配内存的地址传递给它(如堆栈分配的引用)。

【讨论】:

@Vladislav 请注意我在说什么(更新),恕我直言,Xcode 并没有什么不同。 我在析构函数中写了这个array = nullptr; delete array;,它可以工作,但我不确定它是否正确。 @Vladislav “我写了这个array = nullptr; delete array; 这应该总是有效的。虽然如果您使用new [] 进行分配,您将需要delete[] 作为挂件。只是delete 会导致未定义的行为。 @Vladislav array = nullptr; delete array; 不是你想要的。它通过使delete 成为无操作来抑制错误,但是您的析构函数将永远不会真正删除构造函数中的数组newed。 @Vladislav 说得更彻底:如果你这样做,你也可以完全删除 delete []array; 行。这将以相同的方式抑制错误,但不会解决任何问题。【参考方案2】:

delete []apple; 不会编译,但你显然有运行时错误,所以你必须有delete []array;。首先,这是正确

假设您的类几乎是微不足道的,错误的原因可能是 两个 您的 NameClass 对象有一个指向同一数组的 array 指针。如果您的类没有用户定义的复制构造函数和/或赋值运算符,则可能会发生这种情况,在这种情况下,编译器将为您生成一个。如果你然后做这样的事情

NameClass n1;
NameClass n2 = n1;

NameClass n1;
NameClass n2;
n2 = n1;

在您的代码中,编译器只会将所有成员(包括array 指针)相互分配,使array 指向两个对象中的同一块内存(在后一种情况下,导致最初在 n2 的构造函数中分配的内存的内存泄漏)。您需要做的是定义复制构造函数和赋值运算符,以便它们生成array 指向的数组的副本。因为您在析构函数、复制构造函数和复制赋值运算符(以及在构造函数中,但这是显而易见的)中所做的事情必须相互兼容,这被称为Rule of Three。

【讨论】:

以上是关于在类的析构函数中删除数组的主要内容,如果未能解决你的问题,请参考以下文章

Image 类的析构函数和重载 = 运算符

虚析构函数与纯虚函数

从 C++ 中的析构函数中恢复对象?

C++ 虚拟析构函数 (virtual destructor)

基类的析构函数写成virtual虚析构函数

为啥我在这里的析构函数中删除时创建了一个潜在的流浪指针?