2014-01-30 78 views
0

我創建了一個子級,B,爲此,我會打電話給A.創建一個'新'實例解決了析構函數崩潰?

我寫了這個工作代碼的類,所以我要推廣的實際代碼:

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代碼導致我的程序崩潰了'未處理的異常'。

現在,當我爲B類代碼改成這樣:

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

Type *another_var; 
}; 

異常消失。

我認爲我原來的B代碼導致我的程序崩潰,因爲A試圖刪除一個仍然被另一個變量指向的變量。這個推理是否正確?爲什麼B的新代碼會導致我的程序正常工作?

+0

你的推理可能是正確的(不能說沒有看到更多的代碼)。第二個代碼的作用是因爲您爲每個實例創建了一個新對象,所以每次刪除一個對象時,它都不會踩到其他對象的腳趾。但是你的代碼有內存泄漏。你不能只重新分配一個指針而不做一些關於它指向的對象的東西。 – Dave

回答

2

有在你的代碼中的許多缺陷,但一個最有可能導致應用程序崩潰是這一行:

important_variable = another_var; 

another_var不指向任何地方,可以將其刪除。但是important_variable被指向相同的地方,然後在A的構造函數中被刪除。

您的「解決方案」以內存泄漏爲代價掩蓋了問題。當你這樣做

another_var = new Type(); important_variable = another_var; 

原來的動態分配Type對象important_variable指出丟失。

除此之外,您需要遵循rule of three

+0

第一個代碼也有內存泄漏。 – Dave

+0

如何擺脫內存泄漏,仍然保持現有的功能? – Undefined

+0

@Dave是的,它的確如此。 – juanchopanza

0

新增和刪除僅用於處理堆分配。我懷疑在B類的第一個列表中,another_var很可能分配在堆棧上,這是析構函數中導致異常的原因。此外,每當你有一個基類,你真的應該使其破壞者virtual

0

原始版本崩潰,因爲您將important_variable設置爲未初始化的another_var,然後嘗試刪除此未初始化的值。 在「已更正」的版本中,您至少不會刪除未初始化的變量,但仍然包含內存泄漏 - 您將新分配的內存分配給important_variable,然後立即將該值分配給該變量another_var,因此最初分配的內存不是更長的訪問時間並會泄漏。

相關問題