7

Suppose I have a class A and a class B that is derived from A. Now, I want to cast a const A* (called "a") to a B* using dynamic_cast (see below). If "a" really was a B*, then my resulting object pointer should be fine. If "a" was not a B*, then I will get NULL.

const A* a = new B();
const B* b = dynamic_cast<const B*>(a);

For some reason, the dynamic_cast operation causes a SEGFAULT. How can that happen if "a" is NOT NULL? I guess that dynamic_cast will give me a NULL pointer if there were any conversion problems, instead of a SEGFAULT. I should only get a SEGFAULT if I am trying to access "b" and the dynamic cast was unsuccessful, right? I have not even tried to access "b" yet.

So, how can this happen? Is there anything that can cause dynamic_cast to SEGFAULT in the above code, that I am not aware of?

Thanks in advance :-)

EDIT: Running my actual program through GDB gives this output:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) where
#0  0x0000000000000000 in ?? ()
#1  0x00007ffff6c0e612 in __cxxabiv1::__dynamic_cast (src_ptr=<optimized out>, 
src_type=0x4fa6b0, dst_type=0x516bb0, src2dst=0)
at /var/tmp/portage/sys-devel/gcc-4.6.3/work/gcc-4.6.3/libstdc++-v3/libsupc++/dyncast.cc:61

The next line in the output just points to the line in my code where I do the dynamic casting.

pvh1987
  • 621
  • 5
  • 8
  • 12
  • 3
    The problem is in the definition of `A` and `B` – with appropriate definitions your code will work. Therefore, **post a minimal, complete code**! – Konrad Rudolph Jan 09 '13 at 18:27
  • Since your example code is obviously not your real code, are you using `dynamic_cast` to get a reference type instead of a pointer type? In that case, an exception will be thrown. See here: http://ideone.com/uugF37 – Chad Jan 09 '13 at 19:18
  • 2
    Don't "suppose" code to us, write the minimal, compilable test code and *show* us. Otherwise you're asking us to use psychic powers to fix your code. – GManNickG Jan 09 '13 at 19:39

3 Answers3

18

Reasons which can cause a crash when using dynamic_cast

  • pointer points to a free memory block.
  • pointer points to a non-polymorphic type.
  • pointer points to an object with a polymorphic type but present in an external library compiled with RTTI disabled.
  • pointer points to a memory accessing which can cause protection exception (such as a guard page or inaccessible page).

Verify if one of these cases is applicable to you.

Abhijit
  • 62,056
  • 18
  • 131
  • 204
  • 2
    Another possibility is one type being declared in a shared library and compiler being g++. See this for example: http://stackoverflow.com/questions/2351786/dynamic-cast-fails-when-used-with-dlopen-dlsym – Eugene Jan 09 '13 at 18:38
  • Thanks. I do not use external libraries (only wxWidgets but the code that fails does not "touch" wxWidgets objects or anything like that). In my program, class A, is a abstract class with strictly virtual methods (=0 after declaration). The destructor in A is declared as "virtual ~A() {}". Is the GDB output (see edit) any useful to tell what could be wrong? Thanks. – pvh1987 Jan 09 '13 at 19:37
  • @pvh1987: Looks to me its a NULL Pointer exception – Abhijit Jan 13 '13 at 06:47
2

For anyone else like me, you may have accidentally given the cast object the same variable name as the object you were casting it from!

A *name = new B();
B *name = dynamic_cast<B*>(name);

This is clearly wrong with such obvious code however out in the wild mistakes like this can be much harder to spot as variables are dispersed and casts are obfuscated!

Troyseph
  • 4,960
  • 3
  • 38
  • 61
  • this isnt syntactically valid, I don't know how you even got past the compiler – searchengine27 Aug 31 '20 at 20:49
  • 1
    @searchengine27 It compiles if the first variable is declared in some other scope, like a class member variable. Like I said, this is a real late friday night error to make, but leads to the same error mentioned by the asker, so I thought I'd share my stupidity to save some poor tired soul a few minutes in the future – Troyseph Sep 01 '20 at 11:01
0

I got this one once... it was because I'd failed to initialise the pointer, and it was pointing at random garbage.