动态类型转换为什么会导致崩溃?

19

我有一段代码长成这样:

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,对吧?

6个回答

41

导致崩溃的可能原因:

  • obj 指向一个非多态类型的对象(一个没有虚方法的类或结构体,或者是一个基本类型)。
  • obj 指向已经被释放的对象。
  • obj 指向未映射的内存,或者以一种访问时生成异常的方式进行映射(如守卫页或不可访问页)。
  • obj 指向一个具有多态类型的对象,但该类型是在启用RTTI的情况下编译的外部库中定义的。

并不是所有这些问题都会在所有情况下导致崩溃。


我们如何检查对象是否存在? - Mike.R

11
我建议对这段代码片段使用不同的语法。
if (MonitorObjectH1C* monitorObject = dynamic_cast<MonitorObjectH1C*>(obj))
{
    axis = monitorObject->GetXaxis();
}

如果某个线程正在删除monitorObject指向的内容,或者obj是一个错误的垃圾值,仍然可能会导致程序崩溃。但至少你不再需要担心类型转换问题,也不必再进行两次dynamic_cast了。


2
确实,'obj'被另一个线程释放了,这导致了崩溃。感谢您的帮助! - Barth

3

由于它只偶尔崩溃,我敢打赌这是一个线程问题。检查所有对'obj'的引用:

grep -R 'obj.*=' .

2

如果dynamic_cast转换失败并且你正在将其转换为指针,它将返回0,这是你的情况。问题在于你可能在代码中早期破坏了堆,或者没有启用rtti。


2

你确定 'obj' 的值已经正确定义了吗?

例如,如果它未初始化(即随机),那么可能会导致崩溃。


确实,'obj'已被另一个线程释放。感谢您的帮助。 - Barth

1

obj的值能否被不同的线程更改?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接