STL вектор push_back () памяти двойной свободной

Возможный дубликат:
Что такое правило трех?

У меня есть проблема двойного освобождения памяти в следующей программе.

Отладчик показывает, что проблема в push_back() функция.

Класс А:

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

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

Класс Б:

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

Решение

Все остальные уже заговорили об этом, поэтому я не буду погружаться дальше.

Чтобы рассмотреть использование, которое вы, очевидно, пытаетесь выполнить (и соответствует Правилу Трех в процессе исключения), попробуйте следующее. В то время как все абсолютно правы в отношении правильного управления владением динамическими элементами, можно легко создать конкретный образец, чтобы избежать их использования. полностью.

Класс А

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

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

Класс б

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

Другие решения

Вы забыли определить конструктор копирования и оператор присваивания, поэтому ваш обернутый объект deleteнекоторые B…. потом опять когда какая-то копия B выходит за рамки.

В этом случае это B(i) Временная на линии, которую вы определили, а также количество копий, определяемое реализацией в векторе.

Соблюдать правило трех.

6

Проблема в вашем коде связана с тем, что «простые» указатели C / C ++ не имеют понятия владение. Когда указатель копируется, обе копии* «думаю», что они владеют данными, что приводит к двойному удалению.

Признавая этот факт, разработчики стандартной библиотеки C ++ представили unique_ptr<T> класс, который поможет вам решить такие проблемы.


* Одна копия указателя находится в случае B перешел к push_back; другая копия указателя находится в экземпляре, введенном в vector,

4
По вопросам рекламы [email protected]