ошибка сегментации — C ++: dynamic_cast вызывает SEGFAULT, даже если преобразуемый объект не равен NULL. Как это может случиться?

Предположим, у меня есть класс A и класс B, производный от A. Теперь я хочу привести const A * (называемый «a») к B * с помощью dynamic_cast (см. Ниже). Если «a» действительно было B *, то мой результирующий указатель объекта должен быть в порядке. Если «a» не было B *, тогда я получу NULL.

const A* a = new B();
const B* b = dynamic_cast<const B*>(a);

По какой-то причине операция dynamic_cast вызывает SEGFAULT. Как это может произойти, если «a» не равно NULL? Я предполагаю, что dynamic_cast даст мне указатель NULL, если были какие-либо проблемы с конвертацией, вместо SEGFAULT. Я должен получить SEGFAULT, только если я пытаюсь получить доступ к «b», и динамическое приведение не было успешным, верно? Я даже не пытался получить доступ к «б» еще.

Итак, как это может произойти? Есть ли что-то, что может вызвать dynamic_cast для SEGFAULT в приведенном выше коде, о котором я не знаю?

Заранее спасибо 🙂

РЕДАКТИРОВАТЬ: Запуск моей фактической программы через GDB дает такой вывод:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) where
#0  0x0000000000000000 in ?? ()
#1  0x00007ffff6c0e612 in __cxxabiv1::__dynamic_cast (src_ptr=<optimized out>,
src_type=0x4fa6b0, dst_type=0x516bb0, src2dst=0)
at /var/tmp/portage/sys-devel/gcc-4.6.3/work/gcc-4.6.3/libstdc++-v3/libsupc++/dyncast.cc:61

Следующая строка в выводе просто указывает на строку в моем коде, где я выполняю динамическое приведение.

5

Решение

Причины, которые могут вызвать сбой при использовании dynamic_cast

  • указатель указывает на свободный блок памяти.
  • указатель указывает на неполиморфный тип.
  • указатель указывает на объект с полиморфным типом, но присутствует во внешней библиотеке, скомпилированной с отключенным RTTI.
  • указатель указывает на доступ к памяти, что может вызвать исключение защиты (например, защитная страница или недоступная страница).

Убедитесь, что один из этих случаев применим к вам.

13

Другие решения

Для любого другого, как я, вы могли случайно присвоить объекту приведения то же имя переменной, что и объекту, из которого вы его отлили!

A *name = new B();
B *name = dynamic_cast<B*>(name);

Это явно что-то не так с таким очевидным кодом, однако в дикой природе ошибки, подобные этой, могут быть гораздо труднее обнаружить, так как переменные разбросаны, а приведения запутаны!

1

Я получил это один раз … потому что я не смог инициализировать указатель, и он указывал на случайный мусор.

0
По вопросам рекламы [email protected]