2008-11-10 54 views
18

Tôi có một đoạn mã tìm kiếm như thế này:Điều gì có thể khiến báo cáo dynamic_cast bị lỗi?

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

Đôi khi nó bị treo:

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 

tôi không có đầu mối tại sao nó bị treo. obj không phải là rỗng (và nếu nó không phải là một vấn đề, phải không?).

Lý do khiến một diễn viên năng động gặp sự cố?

Nếu không thể truyền, nó chỉ trả về NULL không?

Trả lời

37

Một số nguyên nhân có thể cho sự sụp đổ:

  • obj trỏ đến một đối tượng với một loại không đa hình (một lớp học hoặc struct không có phương pháp ảo, hoặc một loại cơ bản).
  • obj trỏ đến một đối tượng đã được giải thoát.
  • obj điểm vào bộ nhớ chưa được ánh xạ hoặc bộ nhớ đã được ánh xạ theo cách như vậy để tạo ngoại lệ khi được truy cập (chẳng hạn như trang bảo vệ hoặc trang không truy cập được).
  • obj trỏ đến một đối tượng có loại đa hình, nhưng loại đó đã được xác định trong thư viện bên ngoài được biên dịch với RTTI bị vô hiệu hóa.

Không phải tất cả các vấn đề này nhất thiết phải gây ra sự cố trong mọi tình huống.

1

Giá trị của obj có thể thay đổi theo một chuỗi khác không?

+0

Trực giác tốt! Một sợi khác đang giải phóng 'obj'. – Barth

2

dynamic_cast sẽ trả về 0 nếu quá trình truyền không thành công và bạn đang truyền tới con trỏ, trường hợp của bạn. Vấn đề là bạn đã bị hỏng heap trước đó trong mã của bạn, hoặc rtti không được kích hoạt.

2

Bạn có chắc chắn rằng giá trị của 'obj' đã được xác định chính xác không?

Nếu ví dụ như nó chưa được khởi tạo (tức là ngẫu nhiên), tôi có thể thấy nó gây ra sự cố.

+0

Thật vậy, 'obj' được giải phóng bởi một sợi khác. Cảm ơn sự giúp đỡ của bạn – Barth

3

Vì nó chỉ gặp sự cố đôi khi, tôi đặt cược đó là vấn đề về luồng. Kiểm tra tất cả các tham chiếu đến 'obj':

grep -R 'obj.*=' .
11

Tôi khuyên bạn nên sử dụng cú pháp khác cho đoạn mã này.

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

Bạn vẫn có thể sụp đổ nếu một số chủ đề khác được xóa những gì monitorObject điểm đến hoặc nếu obj là điên rác, nhưng ít nhất vấn đề của bạn không được đúc liên quan nữa và bạn không làm dynamic_cast hai lần.

+1

Thật vậy, 'obj' được giải phóng bởi một sợi khác và điều này gây ra sự cố. Cảm ơn bạn đã giúp đỡ ! – Barth

Các vấn đề liên quan