昨天我學到了非常寶貴的一課:遵循三條規則。爲什麼這個「三規則」失敗實際上失敗了?
我想我會學會更容易,但錯誤只出現在刪除語句。這裏是場景:
foo.h
class foo{
public:
...
foo(int *Y);
~foo();
int *X;
}
foo.cpp
...
(.. constructor sets X to Y..)
foo:~foo(){
delete [] X;
}
main.cpp
vector<Foo> fooVec;
{ // this is just to demonstrate scope problems more easily.
Y = new int[10000];
(...init Y...)
fooVec.push(Foo(Y)) // I get it: this calls copy constructor, violating rule of three
(...forget to delete Y...)
}
// Y is now out of scope so this is a memory leak
cout << fooVec[0].[X][0] << " " << fooVec[0].[X][1] // THIS WORKS AS INTENDED DUE TO MEMORY LEAK
// program ends, fooVec goes out of scope
哪些炸彈與"pointer being freed has not been allocated"
。我追蹤回到fooVec超出範圍的地步,這個範圍調用了foos析構函數,它試圖刪除X.我的主要問題是:爲什麼delete實際上會失敗?我從來沒有刪除代碼中的Y(我得到這是一個內存泄漏),所以我實際上並沒有刪除一個指針。此外,內存顯然存在,因爲cout
行的作品。如果這個行失敗了,我本可以早點想出問題的。
下面的評論似乎表明「Foo(Y)
超出範圍時,X被刪除」。但是,如果是這種情況,爲什麼地球上cout
聲明有效?
注:我沒有複製構造函數和賦值超載,因此「三失敗規則」。我得到了我應該擁有的矢量push_back語句。我在問爲什麼不讓他們在這裏殺了我,因爲我忘了釋放Y,所以我實際上並沒有刪除一個指針兩次。
編輯:
謝謝大家的幫助。 user1158692s的回答總結出來了,但是在thelambs回答中的所有評論也幫助我弄清楚究竟發生了什麼,他們一直在爲我回答許多問題。如果我能會同時接受..
我只看到一個析構函數。你的複製構造函數和(複製)指派操作符在哪裏? – peppe
我沒有他們,因此,「三次失敗的規則」。我的問題是,爲什麼不讓他們在這裏殺了我? – Tommy
您將獲得默認的複製構造函數和賦值運算符。哪個會複製指針。現在你有兩個使用相同指針的對象。第一次刪除作品。第二個刪除已被刪除的指針。 –