【问题标题】:delete array pointers heap corruption删除数组指针堆损坏
【发布时间】:2017-01-18 15:47:15
【问题描述】:

我在 Visual Studio 2015 中的这一行遇到异常。它构建时没有错误。

_free_dbg(block, _UNKNOWN_BLOCK);

这就是我声明新指针数组的方式:

CAirship * pAirShip[10];

这就是我删除pAirShip指针数组的方法:

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

我在尝试delete pAirShip[0] 时遇到错误,

这是一个打印指针地址的调试窗口:

这里是完整的代码:

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;
}

【问题讨论】:

  • 你是怎么分配的?
  • 您使用operator new 分配的delete 指针。你有一个带有自动存储的静态指针数组。

标签: c++ arrays pointers heap-corruption


【解决方案1】:

问题在于,在分配任何类型的数组时,C++ 不会初始化元素,而是为它们留下“随机”值。因此,当您创建一个指针数组时,这些指针不是使用NULLnullptr0 值创建的,因此如果它们本身真的未被使用,这并不是一个很好的指标。试图释放未分配的空间是产生错误的原因。您应该在创建数组后立即使用nullptr 初始化它们(在for 循环中自己),然后您可以使用您的代码删除指针数组。

【讨论】:

  • 非常感谢!我在删除它们之前将指针设置为 nullptr。有用!这就是我添加的内容,“pAirShip[i] = nullptr;”
  • 我输入以下内容:CAirship * pAirShip[10]; for(int i=0; i
  • Peja,在将指针初始化为 null 后出现错误。我添加了完整的代码。
  • 当基类的析构函数不是virtual时,通过基类指针删除派生类出现错误——而不是调用派生类的析构函数,而是调用基类的析构函数,这是一个错误。如果您在 CAirship 类声明的公共部分添加“virtual ~CAirship(){}”,您的代码应该可以工作。
猜你喜欢
  • 1970-01-01
  • 2015-08-14
  • 2010-11-20
  • 1970-01-01
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
  • 2019-08-28
  • 1970-01-01
相关资源
最近更新 更多