我正在准备进行C ++测试并遇到了这个代码示例。
在下面的代码示例中,obj被传递给SomeFunc。 SomeFunc有参数Foo obj,因此会产生一个副本,导致创建Foo,然后在SomeFunc函数返回时被销毁。
如果您将功能签名更改为:
SomeFunc(Foo& obj);
或更好:
SomeFunc(const Foo& obj);
问题消失了。
令人费解的是,为什么代码在obj.PrintVal()上崩溃;线。
我可以理解在调用SomeFunc时如何在函数返回时创建和销毁新的Foo,但我认为这将被隔离到SomeFunc中的obj的本地副本。但是当我在调试器中单步执行时,我发现main中的obj的ptr已被释放。等等调用obj.PrintVal() - ptr的解引用会导致分段错误/访问冲突。
有人可以解释一下发生了什么。
#include <iostream>
class Foo
{
public:
int *ptr;
Foo(int i) {
ptr = new int(i);
}
~Foo() {
delete ptr;
}
int PrintVal() {
std::cout << *ptr;
return *ptr;
}
};
void SomeFunc(Foo obj) {
int x = obj.PrintVal();
}
int main() {
{
Foo obj= 15;
SomeFunc(obj);
obj.PrintVal();
}
return 0;
}
答案 0 :(得分:2)
“崩溃”因为您无意中制作了该指针的副本,并且在已删除的指针上调用了delete
。
您需要提供一个复制构造函数(与自动创建的复制构造函数不同),它可以正确处理(为副本创建一个新指针)。