Что может привести к сбою Dynamic_cast?
-
07-07-2019 - |
Вопрос
У меня есть кусок кода, который выглядит так:
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
Я понятия не имею, почему он выходит из строя. объект не является нулевым (и если бы это было так, это не было бы проблемой, не так ли?).
В чем может быть причина сбоя динамического приведения?
Если он не может выполнить приведение, он должен просто вернуть NULL нет?
Решение
Некоторые возможные причины сбоя:
obj
указывает на объект неполиморфного типа (класс или структура без виртуальных методов или фундаментальный тип).obj
указывает на освобожденный объект.obj
указывает на неотображенную память или память, которая была отображена таким образом, что при доступе генерировалось исключение (например, защитная страница или недоступная страница).obj
указывает на объект полиморфного типа, но этот тип был определен во внешней библиотеке, скомпилированной с отключенным RTTI.
Не все эти проблемы обязательно приводят к сбою во всех ситуациях.
Другие советы
Я предлагаю использовать другой синтаксис для этого фрагмента кода.
if (MonitorObjectH1C* monitorObject = dynamic_cast<MonitorObjectH1C*>(obj))
{
axis = monitorObject->GetXaxis();
}
Вы все еще можете потерпеть крах, если какой-то другой поток удаляет то, на что указывает monitorObject, или если obj является сумасшедшим мусором, но, по крайней мере, ваша проблема больше не связана с приведением типов и вы не выполняете dynamic_cast дважды.
Поскольку это происходит сбой только иногда, держу пари, это проблема с многопоточностью. Проверьте все ссылки на 'obj':
grep -R 'obj.*=' .
dynamic_cast вернет 0, если приведение завершится неудачно, и вы приведете к указателю, как в вашем случае. Проблема в том, что вы либо ранее испортили кучу кода, либо rtti не был включен.
Вы уверены, что значение 'obj' было правильно определено?
Если, например, они неинициализированы (то есть случайны), я могу видеть, что это вызывает сбой.
Может ли значение obj быть изменено другим потоком?