2008-11-10 2 views
18

У меня есть кусок кода вида:Что может привести к сбою 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?

ответ

37

Некоторые возможные причины аварии:

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

Не все из этих проблем обязательно приводят к аварии во всех ситуациях.

1

Можно ли изменить значение obj другой темой?

+0

Хорошая интуиция! Другой поток освобождал «obj». – Barth 2008-11-11 07:39:54

2

dynamic_cast вернет 0, если литье закончится неудачно, и вы бросаете указатель, который является вашим случаем. Проблема в том, что вы либо испортили кучу ранее в вашем коде, либо rtti не были включены.

2

Вы уверены, что значение 'obj' было правильно определено?

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

+0

Действительно, 'obj' был освобожден другим потоком. Спасибо за вашу помощь. – Barth 2008-11-11 07:39:20

3

Поскольку он падает только иногда, я уверен, что это проблема с потоками. Проверьте все ссылки на 'obj':

grep -R 'obj.*=' .
11

Предлагаю использовать другой синтаксис для этого фрагмента кода.

if (MonitorObjectH1C* monitorObject = dynamic_cast<MonitorObjectH1C*>(obj)) 
{ 
    axis = monitorObject->GetXaxis(); 
} 

Вы все еще может привести к сбою, если другой поток удаляет то, что monitorObject точки или если OBJ сумасшедший мусор, но, по крайней мере, ваша проблема не литейная связаны больше, и вы не делаете dynamic_cast дважды.

+1

Действительно, «obj» был освобожден другим потоком, и это вызвало сбой. Спасибо за вашу помощь ! – Barth 2008-11-11 07:38:25