返回在堆上存储的类

Zee*_*bit 1 c++ memory visual-studio-2010

我的项目中遇到了与内存相关的崩溃.我设法将其减少到以下"玩具"项目:

class Foo {
public:

    Foo() : bar(nullptr) {
        bar = new int(3);
    }

    ~Foo() {
        if (bar) {
            delete bar;
            bar = nullptr;
        }
    }

private:
    int* bar;
};

Foo test() {
    Foo foo;
    return foo;
}

int main() {
    test();
             // <--- Crash!
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚为什么我在指定的线路上崩溃.这是我到目前为止收集的内容,如果我错了,请纠正我:

基本上,我正在foo堆栈中创建test().Foo在堆上分配一些内存.一切都很好.然后我试着回来foo.foo返回,但它立即被销毁.然后,当我退出时,我再次试图摧毁foo; 因此我Foo两次召唤析构函数,然后崩溃了.我没有得到的是为什么这是一个问题.我Foo::bar在删除它之前检查是否为空,如果我删除它,我之后将其设置为null.

为什么会导致崩溃?我怎样才能解决这个问题?我究竟做错了什么?我很困惑!:(

更新:发生这种情况的主要原因是缺少复制构造函数,如下面的答案中所述.但是,我的原始项目确实有复制构造函数,或者我认为.如果您的类是派生的,那么您必须为派生类显式创建一个复制构造函数.Base(const Derived& other)不算作复制构造函数!

Ben*_*igt 9

你违反了三条规则.

当您在构造函数和析构函数中手动管理内存时,您还必须提供复制构造函数和赋值运算符,否则您的程序将在删除后双重删除并使用内存.

在您的特定示例中,您具有编译器提供的复制构造函数.当foo复制到返回值时test,您有两个具有相同bar指针的对象.本地foo超出范围并被销毁,然后将其bar设置为nullptr.但是副本(返回值)仍然具有非空指针.然后它也被销毁,并再次删除相同的内存.