我为一个我称之为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的新代码会导致我的程序工作?
答案 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
的值,所以最初分配的内存不再可访问并且会泄漏。