0

I get an exception on this line in Visual Studio 2015. It builds with no errors.

_free_dbg(block, _UNKNOWN_BLOCK);

This is how I declare the new array of pointers:

CAirship * pAirShip[10];

This is how I delete the array of pAirShip pointers:

for (int i = 0; i < 10; i++) {
            if (pAirShip[i]) {
            cout << "pAirShip[" << i << "] is " << pAirShip[i] << endl;
            delete pAirShip[i];// Delete appropriate object
    }
        } // end for loop

I get an error on attempting to delete pAirShip[0],

Here is a debug window that does print the pointer addresses:

enter image description here

Here is the full code:

struct AirShipFile {
    int Type;  // Airplane or Balloon
    string name;        // Name of the airship
    int passCount;      // passenger count
    int weightCargo;     // cargo weight
    int EngOrGas;       // engine or gas type
    int distance;       // range or altitude
};
enum EngineType { Jet, Propeller }; // for airplanes only
std::ostream& operator<<(std::ostream& out, const EngineType value) {
static std::map<EngineType, std::string> strings;
if (strings.size() == 0) {
#define INSERT_ELEMENT(p) strings[p] = #p
    INSERT_ELEMENT(Jet);
    INSERT_ELEMENT(Propeller);
#undef INSERT_ELEMENT
    }

return out << strings[value];
}
enum GasType {Helium, Hydrogen };  // for proprellers only
std::ostream& operator<<(std::ostream& out, const GasType value) {
static std::map<GasType, std::string> strings;
if (strings.size() == 0) {
#define INSERT_ELEMENT(p) strings[p] = #p
    INSERT_ELEMENT(Helium);
    INSERT_ELEMENT(Hydrogen);
#undef INSERT_ELEMENT
    }

return out << strings[value];
}
enum AirShipType { AIRPLANE, BALLOON };
class CAirship {
public:
CAirship() { }
virtual void SetData(AirShipFile &data) = 0;
virtual void GetData() = 0;
AirShipType GetAirShipType() { return m_AirShipType; }

protected:
AirShipType m_AirShipType;

};

class CAIRPLANE : public virtual CAirship {
public:
CAIRPLANE() : CAirship() {}
void SetData(AirShipFile &data);
void GetData();

private:
EngineType m_EngineType;
int m_MaxPassengerCount;
string m_Name;
int m_MaxCargoWeight;
int m_MaxAltitude;
};
// Function: SetData
void CAIRPLANE::SetData(AirShipFile &data)
{
// cast integer to enum
m_EngineType = EngineType(data.EngOrGas);
// airplane name
m_Name = data.name;
// passenger count
m_MaxPassengerCount = data.passCount;
//max cargo weight
m_MaxCargoWeight = data.weightCargo;
// cast integer to enum
m_AirShipType = AirShipType(data.Type);
// maximum altitude
m_MaxAltitude = data.distance;

}
void CAIRPLANE::GetData()
{
cout << setw(20) << m_Name << "\t" << setw(20) << m_EngineType << setw(20);
cout << left << setw(20) << m_MaxAltitude << "\n";
}
class CBALLOON : public virtual CAirship {
public:
CBALLOON() : CAirship() {}
void SetData(AirShipFile &data);
void GetData();

private:
GasType m_GasType;
EngineType m_EngineType;
int m_MaxPassengerCount;
string m_Name ;
int m_MaxCargoWeight;
int m_MaxAltitude;
};
void CBALLOON::SetData(AirShipFile &data)
{
// cast integer to enum
m_GasType = GasType(data.EngOrGas);
// airplane name
m_Name  = data.name;
// passenger count
m_MaxPassengerCount = data.passCount;
//max cargo weight
m_MaxCargoWeight = data.weightCargo;
// cast integer to enum
m_AirShipType = AirShipType(data.Type);
// maximum altitude
m_MaxAltitude = data.distance;
}
void CBALLOON::GetData()
{
cout << setw(20) << m_Name << "\t" << setw(20)<< m_GasType << setw(20);
cout << left << setw(20) << m_MaxAltitude << "\n";
}
// AIRPLANE = 0
// BALLOON = 1
int main(int argc, char *argv[])
{
if (argc != 2) {
    cout << "Usage: PR <filename>\n";
    return 1;
}
ifstream Infile(argv[1]);
if (!Infile) {
    cout << "Cannot open file\n";
    return 1;
}
char LineBuf[100];
char d[] = ",";
CAirship * pAirShip[10];
int i = 0;
while (Infile.getline(LineBuf, 100)) {
    struct AirShipFile data;
    // read the first field Airship type
    // airplane or balloon
    data.Type = atoi(strtok(LineBuf, d));
    switch (data.Type) {
    case AIRPLANE:
        // Create AIRPLANE Object
        pAirShip[i] = new CAIRPLANE();
        data.name = strtok(NULL, d);
        data.passCount = atoi(strtok(NULL, d));
        data.weightCargo = atoi(strtok(NULL, d));
        data.EngOrGas = atoi(strtok(NULL, d));
        data.distance = atoi(strtok(NULL, d));
        break;
    case BALLOON:
        // Create BALLOON Object
        pAirShip[i] = new CBALLOON();
        data.name = strtok(NULL, d);
        data.passCount = atoi(strtok(NULL, d));
        data.weightCargo = atoi(strtok(NULL, d));
        data.EngOrGas = atoi(strtok(NULL, d));
        data.distance = atoi(strtok(NULL, d));
        break;
    default:
        break;
    } // end switch
      // call appropriate function
    pAirShip[i++]->SetData(data);
    memset(LineBuf, '\0', 100);
    }
    Infile.close();
    cout << "Listing of all Airplanes \n";
    cout << left << setw(20) << "\nName" << left<< setw(20)<<"\tEngine     Type";
    cout << left<<setw(20)<<"\Maximum Range" << "\n\n";
    for (int i = 0; i < 10; i++) {
    if (pAirShip[i]->GetAirShipType() == AIRPLANE)

        pAirShip[i]->GetData();
    }
    cout << "\n\nListing of all Balloons \n";
    cout <<left << setw(20) << "\nName" << left << setw(20) << "\tGas Type" ;
    cout << left << setw(20) << "\Maximum Altitude" << "\n\n";
    for (int i = 0; i < 10; i++) {
    if (pAirShip[i]->GetAirShipType() == BALLOON)
        pAirShip[i]->GetData();
    }

for (int i = 0; i < 10; i++) {
    if (pAirShip[i]) {

        delete pAirShip[i];// Delete appropriate object
        }
} // end for loop

return 0;
}
James
  • 45
  • 2
  • 9

1 Answers1

2

The problem is that when allocating an array of any kind, C++ does not initialize the elements, but leaves them with "random" values. So, when you create an array of pointers, the pointers are not created with NULL, nullptr or 0 value, so this is not a good indicator if they are really unused on its own. Trying to free the space that isn't allocated is what generates the error. You should first initialize them (by yourself in a for loop) with nullptr right after you create the array, then you can use your code for deleting the array of pointers.

np_6
  • 514
  • 1
  • 6
  • 19
  • Thank you so much! I i set the pointers to nullptr right before I deleted them. It works! This is what I added, "pAirShip[i] = nullptr;"<------- for (int i = 0; i < 10; i++) { if (pAirShip[i]) { pAirShip[i] = nullptr; delete pAirShip[i];// Delete appropriate object } } // end for loop – James Sep 12 '16 at 16:43
  • I ment the following: CAirship * pAirShip[10]; for(int i=0; i<10; i++)pAirChip[i]=nullptr; // your code for processing the CAirship-s //your code for deleting the dynamically allocated CAirships (the first one) What you are doing in your code in the comment is not properly deleting the dynamically allocated CAirship-s,but setting the pointers to nullptr and then using the delete operator on the nullptr pointer,which has no effect (the allocated memory stays allocated).You should use your first code for deleting the pointers, but with the addition of the one line as I explained above. – np_6 Sep 12 '16 at 19:51
  • Peja, I got the error after initializing the pointers to null. I added the full code. – James Sep 14 '16 at 03:13
  • The error occurs when deleting a derived class via a base class pointer when the destructor of the base class is not virtual - rather than calling the destructor of the derived class, the destructor of the base class is called, which is a mistake. Your code should work if you just add 'virtual ~CAirship(){}' in the public section of the declaration of the CAirship class. – np_6 Sep 14 '16 at 14:58