【问题标题】:STL vector push_back() memory double free [duplicate]STL 向量 push_back() 内存双倍释放 [重复]
【发布时间】:2012-11-01 01:58:12
【问题描述】:

可能重复:
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

【问题讨论】:

标签: c++ stl vector push-back


【解决方案1】:

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

底线 除非您有充分的理由,否则不要使用动态分配,并且它由包含变量(如智能指针或大力实践三规则的类)终身保护。

【讨论】:

    【解决方案2】:

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

    鉴于这一事实,C++ 标准库的设计者引入了一个unique_ptr&lt;T&gt; 类来帮助您解决此类问题。


    * 指针的一份副本在B 的实例中传递给push_back;指针的另一个副本在输入到vector 的实例中。

    【讨论】:

    • 在 C++11 中,除了使用 unique_ptr 修复类 B,您还可以编写 vec.emplace_back(i) 而不是 vec.push_back(B(i))。但这是一个问题,即使进行了更改,您仍然需要以一种或另一种方式修复 B
    【解决方案3】:

    您忘记定义复制构造函数和复制赋值运算符,因此您的包装对象是 deleted 由一些 B...。然后当 B 的一些副本超出范围时再次出现。

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

    遵守rule of three

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多