创建一个'new'实例解决了析构函数崩溃的问题?

时间:2014-01-30 22:28:15

标签: c++ destructor delete-operator

我为一个我称之为A的类创建了一个子类B.

我为工作编写了这段代码,所以我将概括实际的代码:

class A
{
public:
  A ()
     {
     important_variable = new Type();
     ...
     };

  ~A (void) { delete(important_variable); };      // Default destructor
  // more methods

protected:
  Type        *important_variable;
};

class B : public A
{
public:
B() : A() { important_variable = another_var; }
~B() {};

Type *another_var;
};

使用此代码导致我的程序因“未处理的异常”而崩溃。

现在,当我将B类的代码更改为:

class B : public A
{
public:
B() : A() { another_var = new Type(); important_variable = another_var; }
~B() {};

Type *another_var;
};

例外情况消失了。

我认为我原来的B代码导致程序崩溃,因为A试图删除另一个变量仍指向的变量。这个推理是否正确?为什么B的新代码会导致我的程序工作?

3 个答案:

答案 0 :(得分:2)

您的代码中存在许多缺陷,但最容易导致崩溃的是这一行:

important_variable = another_var;

another_var没有指出任何可以删除的内容。但important_variable指向同一个地方,然后在A的构造函数中删除。

您的“解决方案”会以内存泄漏为代价来掩盖问题。当你这样做时

another_var = new Type(); important_variable = another_var;

Type指向的原始动态分配的important_variable对象丢失。

除此之外,您还需要关注rule of three

答案 1 :(得分:0)

new和delete仅用于处理堆分配。我怀疑在你的第一个B类列表中,another_var很可能在堆栈上分配,这就是析构函数中导致异常的原因。此外,每当你有一个基类时,你真的应该使它的析构函数virtual

答案 2 :(得分:0)

原始版本崩溃是因为您将important_variable设置为未初始化another_var,然后您尝试删除此未初始化的值。 在“更正”版本中,您至少不删除未初始化的变量,但仍然包含内存泄漏 - 您将新分配的内存分配给important_variable,然后立即为此变量分配another_var的值,所以最初分配的内存不再可访问并且会泄漏。