C ++破坏怪异

时间:2015-02-14 12:18:12

标签: c++

我正在准备进行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;
}

1 个答案:

答案 0 :(得分:2)

“崩溃”因为您无意中制作了该指针的副本,并且在已删除的指针上调用了delete

您需要提供一个复制构造函数(与自动创建的复制构造函数不同),它可以正确处理(为副本创建一个新指针)。