【问题标题】: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 正确地明确说明了他们的要求和限制。
  • 你还需要遵守三法则。

标签: c++ arrays memory-management


【解决方案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

【讨论】:

    猜你喜欢
    • 2015-12-31
    • 2018-09-09
    • 2012-08-11
    • 1970-01-01
    • 2020-04-03
    • 2017-01-11
    • 2013-11-16
    • 2014-12-30
    • 1970-01-01
    相关资源
    最近更新 更多