Что может привести к сбою dynamic_cast?
У меня есть код, похожий на этот:
TAxis *axis = 0;
if (dynamic_cast<MonitorObjectH1C*>(obj))
axis = (dynamic_cast<MonitorObjectH1C*>(obj))->GetXaxis();
Иногда происходит сбой:
Thread 1 (Thread -1208658240 (LWP 11400)):
#0 0x0019e7a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
#1 0x048c67fb in __waitpid_nocancel () from /lib/tls/libc.so.6
#2 0x04870649 in do_system () from /lib/tls/libc.so.6
#3 0x048709c1 in system () from /lib/tls/libc.so.6
#4 0x001848bd in system () from /lib/tls/libpthread.so.0
#5 0x0117a5bb in TUnixSystem::Exec () from /opt/root/lib/libCore.so.5.21
#6 0x01180045 in TUnixSystem::StackTrace () from /opt/root/lib/libCore.so.5.21
#7 0x0117cc8a in TUnixSystem::DispatchSignals ()
from /opt/root/lib/libCore.so.5.21
#8 0x0117cd18 in SigHandler () from /opt/root/lib/libCore.so.5.21
#9 0x0117bf5d in sighandler () from /opt/root/lib/libCore.so.5.21
#10 <signal handler called>
#11 0x0533ddf4 in __dynamic_cast () from /usr/lib/libstdc++.so.6
Я не знаю, почему он падает. obj не является нулевым (и если бы это было не проблема, не так ли?).
В чем может быть причина для динамического броска?
Если он не может отличить, он должен просто вернуть NULL no?
Ответы
Ответ 1
Некоторые возможные причины сбоя:
-
obj
указывает на объект с не полиморфным типом (класс или структура без виртуальных методов или фундаментальный тип).
-
obj
указывает на освобожденный объект.
-
obj
указывает на немаркированную память или память, которая была сопоставлена таким образом, чтобы генерировать исключение при доступе (например, защитная страница или недоступная страница).
-
obj
указывает на объект с полиморфным типом, но этот тип был определен во внешней библиотеке, которая была скомпилирована с отключенным RTTI.
Не все из этих проблем обязательно приводят к сбою во всех ситуациях.
Ответ 2
Я предлагаю использовать другой синтаксис для этого фрагмента кода.
if (MonitorObjectH1C* monitorObject = dynamic_cast<MonitorObjectH1C*>(obj))
{
axis = monitorObject->GetXaxis();
}
По-прежнему может произойти сбой, если какой-либо другой поток удалит объект monitorObject или если obj - сумасшедший мусор, но по крайней мере ваша проблема больше не связана с литьем, и вы не выполняете dynamic_cast дважды.
Ответ 3
Как только он падает только иногда, я делаю ставку на проблему с потоками. Проверьте все ссылки на "obj":
grep -R 'obj.*=' .
Ответ 4
dynamic_cast вернет 0, если бросок не сработает, и вы перейдете к указателю, что является вашим случаем. Проблема в том, что вы либо испортили кучу ранее в вашем коде, либо rtti не был включен.
Ответ 5
Вы уверены, что значение 'obj' определено правильно?
Если, например, это неинициализировано (т.е. случайное), я мог видеть, что он вызывает сбой.
Ответ 6
Может ли значение obj быть изменено другим потоком?