我遇到了以下程序中双重释放内存的问题。
调试器显示问题出在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
答案 0 :(得分:6)
您忘了定义复制构造函数和复制赋值运算符,因此您的包装对象由某些delete
进行B
d ....然后当B
的某些副本出现时超出范围。
在这种情况下,它是您已识别的行上的B(i)
临时值,以及向量中实现定义的副本数。
答案 1 :(得分:4)
代码中的问题是由于“普通”C / C ++指针没有所有权的概念。当指针被复制时,两个副本 * “认为”他们拥有数据,导致双重删除。
认识到这一点,C ++标准库的设计者引入了一个unique_ptr<T>
类,可以帮助您解决类似的问题。
B
的{{1}}的实例中;指针的另一个副本位于输入push_back
。的实例中
答案 2 :(得分:2)
其他人已经在这方面做了很多事情,所以我不会再深入了解。
要解决您显然正在尝试完成的用法(并在消除过程中遵守“三条规则”),请尝试以下操作。虽然每个人对正确管理动态成员的所有权绝对正确,但您可以轻松地制作特定样本以避免使用完全。
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;
}
底线 不要使用动态分配,除非你有充分的理由,和它是由包含的变量(例如智能指针或强力实践三法则的类)所包含的生命保护。