Как удалить указатель на член класса в классе внутри класса - PullRequest
0 голосов
/ 12 июня 2018

У меня есть фрагмент кода, подобный следующему:

class Base {
 public:
  Base(){}
  Base(int in);

  virtual ~Base() { delete b_; }

 private:
  Base *b_;
  int in_;
};

class Derived : public Base {
 public:
  Derived(){}
  ~Derived() {}
};

Base::Base(int i) : in_(in){
  b_ = new Derived();
}

int main() {
  Base *b = new Base(1);
  delete b; 
  return 0;
}

Я получил ошибку сегментации при удалении b_ внутри Base, и я предполагаю, что причина в том, что это приведет к бесконечным рекурсивным вызовам ~База().Я также попытался вызвать ~ Derived () в main (), а затем удалить b, но все еще есть утечка памяти, поскольку b_ не освобождается.

Так что мой вопрос в том, как правильно освободить всю память, если у меня есть такой код.Я искал решение в течение нескольких часов без каких-либо удовлетворительных результатов.Так что любые предложения помогут, спасибо.

1 Ответ

0 голосов
/ 12 июня 2018

Добавление еще одной функции в базовый класс, которая выполняет

delete b_;

и вызов ее в main () перед уничтожением b, решает проблему.

РЕДАКТИРОВАТЬ:

ПослеРаботая полдня, я наконец пришел к следующим выводам:

  1. Код, размещенный в вопросе, компилируется и запускается с GCC, но он дает мне ошибку сегментации, если я компилирую его с помощью встроенного компилятора Mac (clang).) и затем запустите.
  2. Причина 1. удаление b_ внутри ~Base() является рекурсивным вызовом и в конечном итоге приведет к удалению неинициализированного указателя (некоторые неинициализированные b_) в какой-то момент.Если компилируется с GCC, компилятор (или, по крайней мере, мой компилятор) инициализирует b_ в nullptr (я знаю, что в соответствии со стандартами c ++ значение по умолчанию b_ не определено), и поэтому программа завершается нормально.Но с помощью clang компилятору не присваивается b_ конкретное значение по умолчанию, поэтому я получил ошибку сегментации.
  3. Обходной путь - установить b_ на nullptr по умолчанию (в конструкторе по умолчанию дляBase) и добавьте что-то подобное внутрь ~Base(): if (b_ != nullptr) delete b_;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...