I'm having trouble with the (dynamic_cast(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;
}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.