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

时间:2012-11-12 16:10:44

标签: c++ stl vector push-back

  

可能重复:
  What is The Rule of Three?

我遇到了以下程序中双重释放内存的问题。

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

A类:

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

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

B类:

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

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

B::~B() {
    delete a;
}

主要功能:

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;
}

此代码有什么问题?

编辑:错误double free or memory corruption

3 个答案:

答案 0 :(得分:6)

您忘了定义复制构造函数和复制赋值运算符,因此您的包装对象由某些delete进行B d ....然后当B的某些副本出现时超出范围。

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

遵守rule of three

答案 1 :(得分:4)

代码中的问题是由于“普通”C / C ++指针没有所有权的概念。当指针被复制时,两个副本 * “认为”他们拥有数据,导致双重删除。

认识到这一点,C ++标准库的设计者引入了一个unique_ptr<T>类,可以帮助您解决类似的问题。

<小时/> * 指针的一个副本位于传递给B的{​​{1}}的实例中;指针的另一个副本位于输入push_back

的实例中

答案 2 :(得分:2)

注意Rule of Three

其他人已经在这方面做了很多事情,所以我不会再深入了解。

要解决您显然正在尝试完成的用法(并在消除过程中遵守“三条规则”),请尝试以下操作。虽然每个人对正确管理动态成员的所有权绝对正确,但您可以轻松地制作特定样本以避免使用完全

A类

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

A::A(int x) 
   : x(x)
{
}

B类

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

B::B(int x) 
    : a(x) 
{
}

主程序

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;
}

底线 不要使用动态分配,除非你有充分的理由,它是由包含的变量(例如智能指针或强力实践三法则的类)所包含的生命保护。