Есть ли разница между вызовом функции-члена из конечного класса в теле деструктора или из него?

#c #runtime-error #virtual-destructor

#c #ошибка времени выполнения #виртуальный деструктор

Вопрос:

У меня есть конкретный случай, который трудно выделить в приведенном здесь фрагменте кода, но я могу его объяснить…

У меня есть класс A: public B и A имеет указатель на член некоторого типа foo * f. В виртуальном деструкторе для A у меня есть что-то вроде:

 A::~A() { shutdown(); }
  

где завершение работы не является виртуальным и выглядит примерно так:
void A::shutdown() {удалить f;}

оказывается, во время выполнения это дает мне «чисто виртуальный метод с именем terminate, вызываемый без прерывания активного исключения (сброс ядра)», но если я удалю shutdown() из тела деструктора и вызову его напрямую, а затем позволю деструктору запуститься…Я больше этого не понимаю…

Что может быть причиной такого поведения? Я пробовал использовать gdb, но он огромен, и я даже не уверен, что искать. Любые идеи будут очень признательны!

Комментарии:

1. Можете ли вы исключить попытку освободить память от недопустимого указателя?

2. Да, потому что завершение работы тогда работает деструктор, но завершение работы в деструкторе doesnt..it это не тот указатель, который имеет недостатки.

Ответ №1:

Либо shutdown это чисто виртуальная функция где-то в дереве наследования, либо она вызывает другую функцию-член, которая является чисто виртуальной где-то в дереве наследования. Прямо или косвенно, но это то, что происходит.

Проверьте путь выполнения, чтобы увидеть, где выполняется вызов, и избавиться от него.

Комментарии:

1. Ну, shutdown — это невиртуальная функция, которую я определил, я даже могу переименовать ее во что-то другое… все, что он вызывает, это delete f .. я не понимаю, почему выполнение этого вне деструктора конечного класса, а затем вызов пустого деструктора для конечного класса сразу после этого будет отличаться от вызова деструктора конечного класса, который удаляет f …

2. Выполняет ли деструктор для f обратный вызов в A? Возьмите трассировку стека, которая должна быстро идентифицировать виновника.

Ответ №2:

Если A имеет как метод shutdown, так И указатель f, вообще не вызывайте shutdown() . Просто удалите f непосредственно в деструкторе.

Комментарии:

1. Я только что заметил, что другие деструкторы вызываются до того, как этот деструктор вызывается при возвращении из main .. некоторые из них предназначены для объектов, которые, как я предполагаю, вызывают проблему, потому что они каким-то образом привязаны к этому объекту… вызывая shutdown напрямую, он выполняет некоторые действия до того, как будут вызваны какие-либо деструкторы .. это не приводит к сбою, но я все еще проверяю, что это не ошибка .. спасибо!