STL向量push_back()内存双重释放

Ale*_*lex 3 c++ stl vector push-back

可能重复:
三个规则是什么?

我有一个问题,在以下程序中双重释放内存.

调试器显示问题出在push_back()函数中.

A类:

class A {
    public:
        A(int x);
        int x;
};

A::A(int x) {
    this->x = x;
}
Run Code Online (Sandbox Code Playgroud)

B级:

class B {
    public:
        B(int x);
        ~B();
        A* a;
};

B::B(int x) {
    this->a = new A(x);
}

B::~B() {
    delete a;
}
Run Code Online (Sandbox Code Playgroud)

主功能:

int main() {
    vector<B> vec;

    for(int i = 0; i < 10; i++) {
        vec.push_back(B(i)); <------------ Issue is here
    }

    cout << "adding complete" << endl;

    for(int i = 0; i < 10; i++) {
        cout << "x = " << (vec[i].a)->x << endl;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这段代码有什么问题?

编辑:错误double free or memory corruption

Lig*_*ica 6

你忘了定义一个复制构造函数和复制赋值运算符,所以你的包装对象是delete由某些人B...然后当一些副本B超出范围时再次.

在这种情况下,它是B(i)您已识别的临时行,以及向量中实现定义的副本数.

遵守三个规则.


Who*_*aig 2

遵守三法则

其他人已经反复讨论过这一点,所以我不会进一步深入。

为了解决您显然想要完成的用法(并在消除过程中符合三规则),请尝试以下操作。虽然每个人对于动态成员所有权的正确管理都是绝对正确的,但您可以轻松制作特定示例以完全避免使用它们。

A级

class A {
    public:
        A(int x);
        int x;
};

A::A(int x) 
   : x(x)
{
}
Run Code Online (Sandbox Code Playgroud)

B级

class B {
    public:
        B(int x);
        A a;
};

B::B(int x) 
    : a(x) 
{
}
Run Code Online (Sandbox Code Playgroud)

主程序

int main() {
    vector<B> vec;

    for(int i = 0; i < 10; i++) {
        vec.push_back(B(i));
    }

    cout << "adding complete" << endl;

    for(int i = 0; i < 10; i++) {
        cout << "x = " << vec[i].a.x << endl;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

底线 除非有充分的理由,否则不要使用动态分配,并且它由包含的变量(例如智能指针或大力实践“三法则”的类)进行生命周期保护。