如何删除类内部类类型的类成员指针

Posted

技术标签:

【中文标题】如何删除类内部类类型的类成员指针【英文标题】:How to delete a class member pointer of the class type inside the class 【发布时间】:2018-06-12 04:22:55 【问题描述】:

我有一段代码如下:

class Base 
 public:
  Base()
  Base(int in);

  virtual ~Base()  delete b_; 

 private:
  Base *b_;
  int in_;
;

class Derived : public Base 
 public:
  Derived()
  ~Derived() 
;

Base::Base(int i) : in_(in)
  b_ = new Derived();


int main() 
  Base *b = new Base(1);
  delete b; 
  return 0;

我在删除 Base 中的 b_ 时遇到了分段错误,我猜原因是因为它最终会导致对 ~Base() 的无限递归调用。我也尝试在 main() 中调用 ~Derived() 然后删除 b,但是由于 b_ 没有释放,仍然存在内存泄漏。

所以我的问题是,如果我有这样的代码,那么释放所有内存的正确方法是什么。我已经搜索了几个小时的解决方案,但没有得到任何令人满意的结果。所以任何建议都会有所帮助,谢谢。

【问题讨论】:

为什么基类型会知道派生类型? 每个Derived 拥有另一个Derived。那是不可能的。 @codekaizer 感谢您的指出,我已经说得更清楚了。代码是从一个相当复杂的系统中抽象出来的。它的设计只是因为系统需要它。为什么它有这个要求完全不在当前话题...... 我可能会注意到问题的一部分是你有一个虚拟析构函数~Base(),它被非虚拟~Derived()覆盖。老实说,我很惊讶甚至允许这样做。 “在 Base 中删除 b_ 时出现分段错误” - 你是怎么猜到的?您是否设法使用调试器介入其中?因为您显示的代码会在调用任何析构函数之前很久就导致分段错误。 【参考方案1】:

在基类中添加另一个函数

delete b_;

在破坏 b 之前在 main() 中调用它可以解决问题。

编辑:

经过半天的工作,我终于得出以下结论:

    问题中发布的代码使用 GCC 编译和运行,但如果我使用 mac 的集成编译器 (clang) 编译它然后运行,则会出现分段错误。 1. 的原因是删除~Base() 内的b_ 是一个递归调用,最终会在某个时候删除一个未初始化的指针(一些未初始化的b_)。如果使用 GCC 编译,编译器(或至少我的编译器)会将 b_ 初始化为 nullptr(我知道根据 c++ 标准,b_ 的默认值是未定义的),这就是程序正常结束的原因。但是对于 clang,b_ 没有被编译器赋予任何特定的默认值,所以我得到了分段错误。 一种解决方法是默认将b_ 设置为nullptr(在Base 的默认构造函数中)并在~Base() 中添加类似这样的内容:if (b_ != nullptr) delete b_;

【讨论】:

它不能解决问题。它使症状消失。

以上是关于如何删除类内部类类型的类成员指针的主要内容,如果未能解决你的问题,请参考以下文章

如何使用类成员搜索对象指针向量?

当向量在内部类中时,如何删除指向对象的向量指针

删除向量中的指针会导致错误

Qt:更改QPointer时发出信号

如何从 Python 中的类内部访问类方法

c++mfc为何报错不允许指针指向不完整的类类型?