0

In my program I have a base class (ship) and four derived classes (pirate, mercantile, repairing, exploring) and in a member function of repairing I want to know if an object pointed by a ship * is of type pirate in order to be able to handle that case.

So in that member function I have the following if:

ship * shp;

shp = map[i][j]->getShip(); //random initialization of shp

if( (dynamic_cast<pirate *>(shp)) == NULL)  // <- program doesn't enter here  
{ . . . }                                   //      while it should

But during the runtime I noticed that sometimes the program didn't entered the if even when shp was pointing to a non-pirate object (e.g. exploring) .

So I tried to see the result of that boolean value inside the if by writing the following code:

pirate *prt;
bool test;
if(map[i][j]->getShip()!=0){
    prt = dynamic_cast<pirate *>(shp);  //  <- program crashes here
    test = ( prt == NULL );
    cout<<test<<endl;
}

But after compiling and trying to run this, the program crashes just at the time dynamic_cast is used.

So, probably dynamic_cast isn't working correctly and this is the reason it is not entering the if in the previous code.

Note that I have used the same method with dynamic_cast in the rest of my programm to find out the type of an object and it worked properly.

Why is this happening?

Thanks in advance.

Martin G
  • 17,357
  • 9
  • 82
  • 98
thomas_p
  • 97
  • 1
  • 14
  • possibilities: http://stackoverflow.com/questions/278429/what-could-cause-a-dynamic-cast-to-crash – LeleDumbo Jan 07 '15 at 03:06
  • If you're inside the first if statement it implies the casting has failed and shp is probably looking some invalid value. Therefore, the second attempt to dynamic_cast shp (which is likely in an invalid state) will cause crash. You need to post more code for further clarification. – jazaman Jan 07 '15 at 03:09
  • `map[i][j]->getShip()` Are you 100% sure that i and j are valid and you are not stepping out of bounds of map? I assume map is a 2d array. – drescherjm Jan 07 '15 at 03:12
  • 1
    I don't recommend naming your variables the same as standard classes (`map`). – PaulMcKenzie Jan 07 '15 at 03:13
  • `Note that I have used the same method with dynamic_cast in the rest of my programm to find out the type of an object and it worked properly` We don't know what `map` is. We don't know the values of `i` or `j`. Wouldn't it be a little more helpful if you posted what `map` was, and exactly what are the values of `i` and `j` when your program crashes? – PaulMcKenzie Jan 07 '15 at 03:16
  • Problem solved! `dynamic_cast` was crashing because of my mistake. `shp` was not initialized when trying to downcast it, so that's why `dynamic_cast` crashed. @jazaman @PaulMcKenzie I should have posted more code as you said. I suppose the reason it's not entering the first `if` is a mistake in the code that is missing. I ll post the rest of the code if I don't manage to figure out that mistake. Thank you all for your help. – thomas_p Jan 07 '15 at 04:00
  • @PaulMcKenzie: The precise reason we have namespaces is so that `map` is not colliding with `std::map`. This is intentionally OK. – MSalters Jan 07 '15 at 13:07

1 Answers1

0

As you already figured out, the cause was not initializing ship. More fundamentally, dynamic_cast<Derived>(baseptr) requires that baseptr must point to a live Base object or be nullptr. E.g. it won't work either if the pointer was initialized, but the object then deleted.

MSalters
  • 173,980
  • 10
  • 155
  • 350