2008-11-10 24 views
18

Mam kawałek kodu wygląda tak:Co może spowodować awarię dynamic_cast?

TAxis *axis = 0; 
if (dynamic_cast<MonitorObjectH1C*>(obj)) 
    axis = (dynamic_cast<MonitorObjectH1C*>(obj))->GetXaxis(); 

Czasami wywala:

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 

nie mam pojęcia, dlaczego to wywala. obj nie jest pusty (a gdyby był, nie byłby to problem, prawda?).

Co może być powodem rzucenia dynamicznej obsady?

Jeśli nie może rzutować, powinien po prostu zwrócić NULL no?

Odpowiedz

37

Możliwe przyczyny awarii:

  • obj wskazuje na przedmiot z innego typu niż polimorficznych (klasy lub struktury bez metody wirtualne lub podstawowego typu).
  • obj wskazuje na obiekt, który został zwolniony.
  • obj wskazuje na niezmapowaną pamięć lub pamięć, która została zmapowana w taki sposób, aby wygenerować wyjątek podczas dostępu (taki jak strona strażnika lub niedostępna strona).
  • obj wskazuje na obiekt z typem polimorficznym, ale ten typ został zdefiniowany w bibliotece zewnętrznej skompilowanej przy wyłączonym RTTI.

Nie wszystkie z tych problemów powodują awarię we wszystkich sytuacjach.

1

Czy wartość obiektu można zmienić za pomocą innego wątku?

+0

Dobra intuicja! Kolejny wątek zwalniał "obj". – Barth

2

dynamic_cast zwróci 0, jeśli rzutowanie nie powiedzie się i rzutujesz na wskaźnik, co jest twoim przypadkiem. Problem polega na tym, że albo uszkodziłeś stertę wcześniej w kodzie, albo rtti nie został włączony.

2

Czy jesteś pewien, że wartość 'obj' została poprawnie zdefiniowana?

Jeśli na przykład jest niezainicjowany (np. Losowo), widzę, że powoduje awarię.

+0

Rzeczywiście, "obj" został uwolniony przez inny wątek. Dzięki za pomoc – Barth

3

Ponieważ czasami się zawiesza, założę się, że to wątek. Sprawdź wszystkie odniesienia do "obj":

grep -R 'obj.*=' .
11

Proponuję użyć innej składni tego fragmentu kodu.

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

Nadal można zawiesić, jeśli jakiś inny wątek jest usuwanie co monitorObject punktów lub jeśli obj fiksuje śmieci, ale przynajmniej problem nie rzuca już związane i nie robisz z dynamic_cast dwukrotnie.

+1

Rzeczywiście, "obj" został uwolniony przez inny wątek, co spowodowało awarię. Dzięki za pomoc ! – Barth