I'm having trouble with the (dynamic_cast<Truck*>(vptr[k])) -> DOTLicense() part.

If my numOfVehicles = 1 it works fine, but if numOfVehicles > 1 I get core dump error. I can remove the dynamic_cast statement and it works for numOfVehicles > 1. Any help or advise on what I'm doing wrong is appreciated.

int main()
{

  const size_t maxNumOfVehicles(100);
  const size_t maxSnSize(20);
  const size_t maxDotSize(20);
  size_t numOfVehicles;

  std::cout << "Tracker started..." << std::endl;

  // get the number of vehicles
  std::cin >> numOfVehicles;

  // Create an array of vehicle pointers
  Vehicle* vptr[maxNumOfVehicles];
  VehicleType v;  // used to return an enum value
  char sn [maxSnSize];
  unsigned int passengerCap;
  char dotLicense[maxDotSize];
  float d1;
  float d2;
  float d3;

  while((numOfVehicles != 0) && (numOfVehicles < maxNumOfVehicles)) // Begin
    { 
    
      // Process the vehicle segment
      for(size_t i=0;i<numOfVehicles;++i) // Begin first for loop
	{

	  // get the vehicle serial number and check it
	  std::cin >> std::setw(maxSnSize) >> sn;
	  v = Vehicle::SnDecode(sn);
	  if(v == badSn) break; // don't process - can't make vehicle object

	  // get the passenger capacity
	  std::cin >> passengerCap;
	  
	  switch(v) // Begin switch
	    {
	    case vehicle:
	      vptr[i] = new Vehicle(sn, passengerCap);
	      break;
	    case car:
	      vptr[i] = new Car(sn, passengerCap);
	      break;
	    case truck:
	      std::cin >> std::setw(maxDotSize) >> dotLicense;
	      vptr[i] = new Truck(sn, passengerCap, dotLicense);
	      break;
	    case van:
	      std::cin >> std::setw(maxDotSize) >> dotLicense;
	      std::cin >> d1;
	      std::cin >> d2;
	      std::cin >> d3;
	      vptr[i] = new Van(sn, passengerCap, dotLicense, d1, d2, d3);
	      break;
	    case tanker:
	      std::cin >> std::setw(maxDotSize) >> dotLicense;
	      std::cin >> d1;
	      std::cin >> d2;
	      vptr[i] = new Tanker(sn, passengerCap, dotLicense, d1, d2);
	      break;
	    case flatbed:
	      std::cin >> std::setw(maxDotSize) >> dotLicense;
	      std::cin >> d1;
	      std::cin >> d2;
	      vptr[i] = new Flatbed(sn, passengerCap, dotLicense, d1, d2);
	      break;
	    default:
	      std::cerr << "**Error: bad serial number passed to decision logic\n";
	      break;
	    } // end switch


	} // end first for loop            

	  // Send Report to Std. Output
	      std::cout << "Type  Pass Cap  Load Cap  DOT License  Serial Number\n";
	      std::cout << "----  --------  --------  -----------  -------------\n";
	      
	  for(size_t k=0;k<numOfVehicles;++k) // begin second for loop
	    {

	      if(truck <= v) // begin if statement
		{
		  std::cout << " " << vptr[k] -> ShortName() << "         " << vptr[k] -> PassengerCapacity() << "      " << vptr[k] -> LoadCapacity() << "  " << (dynamic_cast<Truck*>(vptr[k])) -> DOTLicense() << "  " <<  vptr[k] -> SerialNumber() << "\n";
		}
	      else
		{
		  std::cout << " " << vptr[k] -> ShortName() << "         " << vptr[k] -> PassengerCapacity() << "      " << vptr[k] -> LoadCapacity() << "  (NA)  " <<  vptr[k] -> SerialNumber() << "\n";
		} // end if statement

	      delete vptr[k];
	    } // end second for loop


      // Finished processing vehicle segment. Wait for next segment.
      std::cout << "Tracker started..." << std::endl;
      std::cin >> numOfVehicles;

          } // end while loop

  // Bye Bye message
  std::cout << "...Thank you for using Tracker.\n";

  return 0;
}

Recommended Answers

All 2 Replies

Hard to say without a better idea of how your different classes relate to one another.

What type is vptr for example?

Separating the code into two functions
- input data
- print data
would help with following what's going on.

if(truck <= v) // begin if statement
        {
          ... (dynamic_cast<Truck*>(vptr[k])) -> DOTLicense() ...
        }
          else
        {
          ...
        } // end if statement

the dynamic_cast operator in c++ is a run-time cast operator; the corrctness of the result of the cast is guaranteed by the implementation if the cast succeeds. if it fails, the result of a dynamic cast on a pointer is a zero pointer. and if you try to use the result without checking for succeess, a failed cast will cause unpleasant things to happen; typically a core dump.
assuming that the variable v has the right value of the VehicleType enum, if( truck <= v ) would be true for things other than a truck. and if that happens, (dynamic_cast<Truck*>(vptr[k])) would result in a zero pointer which you are trying to dereference. that the failure occurs at precisely the second element of the array is probably because you are using the same inputs every time to test your code. to debug the current code, print out the following:

Truck* pointer = (dynamic_cast<Truck*>(vptr[k])) ;
std::cout << "pointer: " << pointer 
                 << "  type of object: " << typeid( *(vptr[k]) ).name() << '\n' ;

unless you are trying to learn about dynamic_casts, consider using virtual functions instead of the type variable and casts.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.