2015-01-13 36 views
0

[編輯帖子,基於之前的回答和評論。我已經嘗試了幾種策略,其中沒有任何一種可行。]帶指針變量的C++分段故障類

我有一個類D,帶有類型爲E的成員變量.E有兩個子類,E1和E2。當我嘗試下面的代碼時,我遇到了分段錯誤(請參閱下面的詳細輸出)。有人能告訴我爲什麼,並提供更改的代碼,將使其工作?謝謝。

任何有關可接受或專業編碼風格的意見都會受到歡迎。


#include <iostream> 
#include <vector> 

using std::cout; 
using std::endl; 
using std::vector; 

class E { 
    public: 
     E() {cout << "In E constructor" << endl;} 

     virtual ~E() {cout << "In E destructor" << endl;} 
}; 

class E1 : public E { 
    public: 
     E1() {cout << "New E1" << endl;} 

     ~E1() {cout << "In E1 destructor" << endl;} 
}; 

class E2 : public E { 
    public: 
     E2() {cout << "New E2" << endl;} 

     ~E2() {cout << "In E2 destructor" << endl;} 
}; 

class D { 
    public: 
     D(const vector<int>& a, int b) 
     { 
      cout << "y1" << endl; 
      if (b == 1) 
       p = new E1(); 
      else 
       p = new E2(); 
     } 

     D() {cout << "y2" << endl; p = new E1();} 

     ~D() {if (p != nullptr) {cout << "x" << endl; delete p;}} 

    private: 
     E *p; 
}; 

int main(int argc, char **argv) 
{ 
    D d; 

    vector<int> a; 
    a.push_back(1); 

    int b = 2; 

    d = D(a, b); 
} 

這裏的輸出。

y2 
In E constructor 
New E1 
y1 
In E constructor 
New E2 
x 
In E2 destructor 
In E destructor 
x 
Segmentation fault 
+0

http://meta.stackexchange.com/a/129632/165773 – gnat

+2

你的問題已經正確說明,但在Programmers SE上這是題外話。由於@gnat已經鏈接,您可以在網站的策略中找到與主題相關的設計問題與應該針對Stack Overflow的實現問題之間的分離。 – logc

回答

0

由於聲明,您的原始代碼會刪除新的E2對象。

d = D(a, b); 

由於您沒有提供賦值運算符,因此編譯器將提供成員賦值實現。緊接着分配之後,變量d和從D(a,b)創建的臨時的未命名的變量將具有指向相同E2對象的成員變量p

將在d和未命名的變量上調用D ::〜D()析構函數。刪除E2對象會導致分段錯誤。

+0

我刪除了刪除語句,程序工作。然後,我將delete語句更改爲'if(p!= nullptr)delete p'。我再次遇到了分段錯誤。任何見解?謝謝。 –

+0

@ tr1944您的默認構造函數不會將p初始化爲nullptr,因此您不確定它的值。 – user2313067

+0

默認的複製賦值運算符(和複製構造函數)執行*成員*的複製,而不是按位複製。不是說這對原始類型有很大的實際區別。 –