#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 напрямую, он выполняет некоторые действия до того, как будут вызваны какие-либо деструкторы .. это не приводит к сбою, но я все еще проверяю, что это не ошибка .. спасибо!