关于c ++:STL向量push_back()内存双重免费

STL vector push_back() memory double free

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
What is The Rule of Three?

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

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

甲级:

1
2
3
4
5
6
7
8
9
class A {
    public:
        A(int x);
        int x;
};

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

乙类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class B {
    public:
        B(int x);
        ~B();
        A* a;
};

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

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

主要功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main() {
    vector 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


您忘记了定义一个复制构造函数和复制分配操作符,所以您包装的对象正被一些B使用deleted。然后,当一些B的拷贝超出范围时。

在这种情况下,它是您所标识的行上的B(i)临时文件,以及向量内的实现定义的副本数。

遵守三条规则。


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

为了认识到这一事实,C++标准库的设计者引入了一个EDCOX1×4类,它帮助您解决这样的问题。


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


注意三个规则

其他人都已经认真讨论过了,所以我不会再往下潜了。

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

甲类

1
2
3
4
5
6
7
8
9
10
class A {
    public:
        A(int x);
        int x;
};

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

乙类

1
2
3
4
5
6
7
8
9
10
class B {
    public:
        B(int x);
        A a;
};

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

主程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main() {
    vector 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;
}

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