gpt4 book ai didi

c++ - 为什么这个 "rule of three"失败实际上失败了?

转载 作者:太空狗 更新时间:2023-10-29 23:40:30 25 4
gpt4 key购买 nike

昨天我学到了一个非常宝贵的教训:遵循三原则。

我想我会更容易学会,但错误只出现在 delete 语句上。这是场景:

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

哪个炸弹带有 “正在释放的指针尚未分配”。我追溯到 fooVec 超出范围的那一点,它调用 foos 析构函数,它试图删除 X。我的主要问题:为什么删除实际上失败了?我从未在代码中删除 Y(我知道这是内存泄漏),所以我实际上并没有双重删除指针。此外,内存显然存在,因为 cout 行有效。如果这条线路失败了,我会更快地找出问题所在。

下面的评论似乎表明“当 Foo(Y) 超出范围时,X 被删除”。但如果是这样的话,为什么 cout 语句会起作用?

注意:我没有复制构造函数和赋值重载,因此是“三败法则”。由于 vector push_back 语句,我得到了我应该拥有的。我在问为什么不让他们在这里杀了我,因为我忘记释放 Y 所以我实际上并没有删除一个指针两次。

编辑:

谢谢大家的帮助。 user1158692s 的回答总结了它,但是 thelambs answer 中的所有评论也帮助我弄清楚到底发生了什么,他们留下来为我回答了很多问题。如果可以的话,我会接受这两个......

最佳答案

[注意:newFoo 不再是原帖的一部分,它指的是被插入 vector fooVec 的对象,现在就地完成了:foovec.push_back( Foo(Y) )]

确实双重删除。首先,当 newFoo 超出范围时,它执行 delete[] x(这是第一次删除)。你在这里写了forget to delete Y,但是Y实际上被newFoo的desctuctor删除了。

第二次删除是当 newFoo 的拷贝被删除时(当 fooVec 超出范围时)。 newFoo 的拷贝也执行 delete[] x,并且由于您没有复制构造函数,xnewFoo 中是相同的,并且在 newFoo 的拷贝中,因此它是一个双删除。

现在,您将无法轻松解决此问题。因为在您要编写的复制构造函数中,您不知道如何复制 x(它有多少个元素?1?100000?)。

关于c++ - 为什么这个 "rule of three"失败实际上失败了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19519364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com