2012-11-12 32 views
2

可能重複:
What is The Rule of Three?STL矢量的push_back()存儲器雙自由

我的存儲器中的以下程序的雙重釋放的問題。

調試器顯示問題出在push_back()函數中。

類A:B

class A { 
    public: 
     A(int x); 
     int x; 
}; 

A::A(int x) { 
    this->x = x; 
} 

類別:

class B { 
    public: 
     B(int x); 
     ~B(); 
     A* a; 
}; 

B::B(int x) { 
    this->a = new A(x); 
} 

B::~B() { 
    delete a; 
} 

主要功能:

int main() { 
    vector<B> vec; 

    for(int i = 0; i < 10; i++) { 
     vec.push_back(B(i)); <------------ Issue is here 
    } 

    cout << "adding complete" << endl; 

    for(int i = 0; i < 10; i++) { 
     cout << "x = " << (vec[i].a)->x << endl; 
    } 

    return 0; 
} 

什麼是錯誤的第是代碼?

編輯:錯誤double free or memory corruption

+1

你看到了什麼錯誤? –

+1

http://stackoverflow.com/questions/4172722/what-is-the-rule-of-reeree –

+1

請參閱http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three – hmjd

回答

2

聽取Rule of Three

其他人都已經重彈這個,所以我不會進一步深入。

爲了解決您顯然想要完成的使用(並且符合排除過程中的三法則),請嘗試以下操作。雖然每個人都對動態會員的所有權的正確管理絕對正確,但您可以輕鬆制定具體樣本,以避免其使用完全

A類

class A { 
    public: 
     A(int x); 
     int x; 
}; 

A::A(int x) 
    : x(x) 
{ 
} 

B類

class B { 
    public: 
     B(int x); 
     A a; 
}; 

B::B(int x) 
    : a(x) 
{ 
} 

主程序

int main() { 
    vector<B> vec; 

    for(int i = 0; i < 10; i++) { 
     vec.push_back(B(i)); 
    } 

    cout << "adding complete" << endl; 

    for(int i = 0; i < 10; i++) { 
     cout << "x = " << vec[i].a.x << endl; 
    } 

    return 0; 
} 

底線 不要使用動態分配,除非您有充分的理由,它被包含的變量(如智能指針或強有力地實踐三法則的類)所保護。

6

你忘了定義拷貝構造函數和一些B拷貝賦值運算符,讓你的包裝對象正在delete d ....當再次的B一些副本熄滅的範圍。

在這種情況下,它是您確定的行上的臨時文件B(i),以及向量中的實現定義數量的副本。

遵守rule of three

4

代碼中的問題是由於「普通」C/C++指針沒有所有權的概念。當指針被複制時,兩個副本*「認爲」他們擁有數據,導致雙重刪除。

爲了認識到這個事實,C++標準庫的設計者引入了一個unique_ptr<T>類來幫助你解決這樣的問題。


*指針的一個副本在 B的實例中傳遞給 push_back;指針的另一個副本在輸入到 vector的實例中。

+2

在C++ 11中,以及使用'unique_ptr'修復類'B',你可以寫'vec.emplace_back(i)'而不是'vec.push_back(B(i))'。但是,這是一個旁白,即使有這種變化,你仍然需要修復'B',這種或那種方式。 –