SEGFAULT - На C ++ чистые виртуалы. Зачем? - PullRequest
0 голосов
/ 05 апреля 2011

Я передаю указатель чисто виртуального базового класса через код C как void *.

Когда я разыменую базовый класс в C ++, отладчик может получить доступ ко всем его членам. Однако, когда я пытаюсь получить доступ к чисто виртуальной функции, это SEGFAULTs / Access Violation. «Невозможно получить доступ к памяти в 0xc», - говорит отладчик (когда я пытаюсь получить доступ к чисто виртуальной функции).

Возможно , что функция вызывается до возврата конструктора, будет ли это иметь значение? Что еще я должен искать? Все остальные переменные, похоже, не повреждены.

Код:

the_socket_base* thisptr = reinterpret_cast<the_socket_base*>(watcher->data);  
thisptr->CallPureVirtualFunction();  
delete thisptr;
thisptr->CallSecondPureVirtualFunction();  //OOPS! It crashed
...  
watcher->data = this; // Associate socket with the watcher (Where 'this' is the base class)  
// NOTE THAT THE ABOVE ALWAYS HAPPENS IN THE CONSTRUCTOR

ОБНОВЛЕНИЕ : код частично работает, и я подозреваю, что объект удаляется. Потому что он запускает обработчик чтения (который может удалить себя), а затем запускает обработчик записи без проверки ... Так что, вероятно, так оно и есть.


Ответ

ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ : Я хотел уточнить, что комментарий Кита был правильным. Я удалял объект и пытался получить к нему доступ после того, как он был удален. Очень простая ошибка! delete this; хитрая ловушка. Спасибо за все комментарии.

Ответы [ 2 ]

2 голосов
/ 05 апреля 2011

Без кода, сложно сказать. Две возможности OTOH:

  • Вы вызываете виртуальные функции прямо или косвенно из конструктора или деструктора - вы не можете этого сделать.
  • Вы используете множественное наследование - и ваш кастинг через void * перерывы
0 голосов
/ 05 апреля 2011
delete this; // Is dangerous, use with care

Что я делал, так это удалил это; в чисто виртуальной функции, возвращаясь немедленно, а затем вызывая другую чисто виртуальную функцию для уже удаленного объекта.

  • Чистый виртуальный vtable не будет работать, когда объект уже удален
...