昨天我学到了非常宝贵的一课:遵循三法则。
我想我会更容易学会它,但错误只出现在删除语句上。这是场景:
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。我的主要问题:为什么删除实际上失败了?我从未在代码中删除 Y(我知道这是内存泄漏),所以我实际上并没有双重删除指针。此外,内存显然存在,因为cout
线路有效。如果这条线失败了,我会更快地发现问题。
下面的评论似乎表明“当Foo(Y)
超出范围时,X 被删除”。但如果是这样的话,为什么这个cout
说法会奏效呢?
注意:我没有复制构造函数和赋值重载,因此是“三失败规则”。由于 vector push_back 语句,我知道我应该拥有。我在问为什么不让他们在这里杀了我,因为我忘记释放 Y 所以我实际上并没有删除指针两次。
编辑:
谢谢大家的帮助。user1158692s answer总结了它,但是thelambs answer中的所有评论也帮助我弄清楚了到底发生了什么,他们坚持为我回答了许多问题。可以的话两个都接受。。