在类的析构函数中删除数组
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
成为无操作来抑制错误,但是您的析构函数将永远不会真正删除构造函数中的数组new
ed。
@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。
【讨论】:
以上是关于在类的析构函数中删除数组的主要内容,如果未能解决你的问题,请参考以下文章