【问题标题】:Deleting array memory for a pointer member variable删除指针成员变量的数组内存
【发布时间】:2018-05-05 20:38:36
【问题描述】:

我正在阅读一本教科书,它似乎表明当你有一个指针成员变量时,你必须将代码放入析构函数中才能删除内存。
有点不清楚,但似乎代码必须如下所示:

private:  
double *aPtr;

public:  
~NumberArray(){ delete [ ] aPtr;}

这不是因为析构函数已经删除了该数组中的第一个元素,所以最终不是 2 个删除命令吗?此外,即使您的程序中有 1 行或更多行用于默认析构函数,析构函数是否会自动执行其默认工作?程序是先执行你的代码还是在析构函数的“自动”部分执行代码?

出于某种原因,我认为删除命令只是用于动态分配的内存。我想我错了?

【问题讨论】:

  • "当你有一个指针成员变量时,你必须在析构函数中放入代码才能删除内存",为什么?指针不必指向必须“删除”的内存。
  • “析构函数已经在删除该数组中的第一个元素” - 它在哪里做呢?您的析构函数仅调用 delete[] 运算符。你也没有默认析构函数,因为你重载了它
  • 析构函数会删除指针本身。由于指针是plain old data,它实际上什么都不做。是否必须为指针指向的 contents 添加delete 取决于。如果该类“拥有”指向的内容(并且不与其他所有者共享)它应该。否则,它不应该。并且,请根据指针指向的内容考虑是使用delete 还是delete[]
  • 顺便说一句。析构函数和delete 是不同的东西。尽管delete 为指向对象调用析构函数(假设为非nullptr),但也为任何其他构造对象调用析构函数。当“超出范围”时,作为局部变量实例化的类被破坏 - delete-ing 这将是非法的。离开main() 后,全局变量中的构造对象被破坏 - 再次没有delete。更不用说对使用placement new构造的实例的显式析构函数调用...
  • 您可能会将“指向数组第一个元素的指针”与“数组的第一个元素”混淆。

标签: c++ arrays destructor


【解决方案1】:

这不是因为析构函数已经删除了该数组中的第一个元素,所以最终不是 2 个删除命令吗?

析构函数正在破坏 指针(这是一个无操作)。但它根本没有触及指针指向的内容。所以没有任何删除操作,除非你自己明确写一个。

此外,析构函数是否会自动执行其默认工作,即使您的程序中有 1 行或多行用于默认析构函数?

是的,析构函数总是会销毁对象的成员和基类(在执行析构函数体之后)。但同样,该成员是aPtr。这不是aPtr 指向的任何东西。

程序是先执行你的代码还是在析构函数的“自动”部分执行代码?

对象的任何成员在析构函数体中仍然存在。这是有道理的,因为清理相关操作可能需要它们。在那之后,它们确实被摧毁了。

【讨论】:

  • delete 相反,delete[] 确实为数组的每个元素调用了析构函数。在 OP 的示例中,元素是双精度的,因此每个元素的析构函数都很简单,但这是一个完全不同的问题。
  • @MichaëlRoy - 你到底指的是我的答案的哪一部分?
  • “析构函数....但它根本没有触及指针指向的东西。”调用delete[]时根本不是这种情况
  • @MichaëlRoy - OP 认为有 2 个删除操作。一个是自动的,一个是delete[]。事实并非如此,我强调的是。
【解决方案2】:

您似乎对deletedelete[] 之间的区别有点困惑。

delete(不带括号)的第一种形式,用于销毁分配给单个对象的动态内存。这种形式不应该用在数组上,因为在这种情况下,编译器只会调用一次析构函数。

带有方括号的第二种形式保证在释放用于数组的内存之前,将为动态分配的数组的每个元素调用析构函数。

简而言之:

// first form:
SomeClass* object = new SomeClass;
delete object;                     // SomeClass::~SomeClass is called once, which is good.

// second form
SomeClass* array = new SomeClass[N]; // SomeClass::SomeClass() is called N times.
delete[] array;      // SomeClass::~SomeClass is called N times, which is good.
delete array;        // YIKES!! SomeClass::~SomeClass is called only once. 
                     // This is terrible, as N-1 destructors did not get called.

【讨论】:

  • OP 对析构函数自动做什么和不做什么感到困惑。
猜你喜欢
  • 2014-07-25
  • 1970-01-01
  • 2019-03-31
  • 2015-08-09
  • 2021-06-25
  • 1970-01-01
  • 1970-01-01
  • 2015-02-15
  • 2014-04-19
相关资源
最近更新 更多