Создание «нового» экземпляра решает крах деструктора?

0

Я создал подкласс класса B для класса, который я назову A.

Я написал этот код для работы, поэтому я собираюсь обобщить фактический код:

class A
{
public:
  A ()
     {
     important_variable = new Type();
     ...
     };

  ~A (void) { delete(important_variable); };      // Default destructor
  // more methods

protected:
  Type        *important_variable;
};

class B : public A
{
public:
B() : A() { important_variable = another_var; }
~B() {};

Type *another_var;
};

Наличие этого кода для B вызвало сбой моей программы с помощью "Необработанного исключения".

Теперь, когда я меняю код для класса B на это:

class B : public A
{
public:
B() : A() { another_var = new Type(); important_variable = another_var; }
~B() {};

Type *another_var;
};

Исключение уходит.

Я думаю, что мой исходный код для B вызвал мою программу, потому что A пытался удалить переменную, на которую все еще указала другая переменная. Правильно ли это рассуждение? Почему новый код для B заставляет мою программу работать?

  • 0
    Ваши рассуждения, вероятно, верны (не могу сказать, не увидев больше кода). Второй код работает, потому что вы создаете новый объект для каждого экземпляра, поэтому каждый раз, когда вы удаляете один, он не наступает другим. Но ваш код имеет утечки памяти. Вы не можете просто переназначить указатель, не делая что-то с объектом, на который он указывал.
Теги:
delete-operator
destructor

3 ответа

2
Лучший ответ

В вашем коде есть много недостатков, но наиболее вероятным причиной сбоя является эта строка:

important_variable = another_var;

another_var не указывает нигде, что можно удалить. Но important_variable указывается на одно и то же место, а затем удаляется в конструкторе A

Ваше "решение" маскирует проблему за счет утечки памяти. Когда вы это сделаете

another_var = new Type(); important_variable = another_var;

исходный динамически выделенный объект Type который указывает important_variable, потерян.

Кроме того, вам нужно следовать правилу из трех.

  • 0
    первый код также имеет утечку памяти.
  • 0
    Как я могу избавиться от утечки памяти, сохраняя при этом существующую функциональность?
Показать ещё 4 комментария
0

new и delete предназначены только для распределения кучи. Я подозреваю, что в вашем первом списке класса B в стеке скорее всего выделяется another_var и именно это вызывает исключение в деструкторе. Кроме того, всякий раз, когда у вас есть базовый класс, вы действительно должны сделать его деструктор virtual.

0

Исходная версия разбилась, потому что вы установили important_variable в uninitialised another_var а затем попытались удалить это неинициализированное значение. В "исправленной" версии вы, по крайней мере, не удаляете неинициализированные переменные, но все же в ней содержится утечка памяти - вы назначаете новую выделенную память important_variable а затем сразу же присваиваете этой переменной значение another_var, поэтому первоначально выделенная память больше не доступный и протекающий.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню