3

エラーが発生しました - ヒープが破損しています。理由がわかりません。

私の拠点:

時間:

class Base
{
public :
    Base(char* baseName, char* cityName);
    virtual ~Base();

    list<Vehicle*>::const_iterator GetEndList();
    void PrintAllVehicles(ofstream &ResultFile) const;
    char* GetBaseName() const;
    char* GetLocation() const;
    void InsertNewVehicleToBase(Vehicle* newVehicle);
    list<Vehicle*>::const_iterator FindVehicle(char* id);
    void RemoveVehicle (list<Vehicle*>::const_iterator beg);



 private:
    char* m_name;
    char* m_location;
    list<Vehicle*> m_baseVehicles;

};  

cpp :

Base::Base(char* baseName, char* cityName)
{
    m_name = new char [strlen(baseName)+1];
    strcpy(m_name, baseName);
    m_location = new char [strlen(cityName)+1];
    strcpy(m_location, cityName);
}

Base::~Base()
{
    delete [] m_name;
    delete [] m_location;
    //m_baseVehicles.clear();
}

アーミーデストラクタ:

Army::~Army()
{
    list<Base*>::iterator baseIter = m_basesList.begin();
    for (baseIter ; baseIter != m_basesList.end() ; ++baseIter)
        delete (*baseIter);
    m_basesList.clear();
 }  

私は何を間違っていますか?

4

6 に答える 6

7

このコードの目に見える問題:

  • std::string ではなく char* を使用するには、手動のメモリ管理が必要です
  • STL コンテナーで生ポインターを使用すると、クリーンアップ コードが過度に複雑になる
  • 文字列操作に CRT を使用するのは C++ の「コードの匂い」です
于 2010-09-27T14:50:13.373 に答える
7

表示されたコードには明らかな問題はありません。表示されていないコードにエラーがある可能性があります。

私にとって最も疑わしいのは、Baseクラスが 2 つのポインターを所有し、コピー コンストラクターまたは代入演算子が定義されていないことです。これは、Baseオブジェクトをコピーすると、2 つのBaseオブジェクトが同じデータを指すことになり、それらが破棄されると 2 回削除され、ヒープが破損することを意味します。

Armyクラスにもこの問題がある可能性があります (複数のポインターを所有しているため)Baseが、クラスの定義を示していないため、コピー コンストラクターと代入演算子があるかどうかは明らかではありません。

最後に、Baseオブジェクトが割り当てられている場所を示していません。それらがオブジェクトに渡され、Armyオブジェクトの外部のどこかで削除される可能性はありArmyますか? それとも、オブジェクトにBase*含まれているArmyオブジェクトが、削除してはならないスタック上のオブジェクトを参照している可能性がありますか?

于 2010-09-27T14:50:41.533 に答える
5

指定されたコードに問題はありません。しかし、この種のコードでは、複数の削除の可能性が高くなります。つまり、メモリ ブロックを 2 回削除すると、ヒープが破損します。

于 2010-09-27T15:28:14.503 に答える
3

問題のあるコードの部分は投稿しませんでした。すべてがかなり正常に見えるためです。ただし、多くの const-correctness 問題があります。

Base(char* baseName, char* cityName);

const char*文字列は、変更されていない限り、として渡す必要があります。

virtual ~Base();

これが必要かどうかはわかりませんvirtual。そのサブクラスが何であるかを見ることができません。

list<Vehicle*>::const_iterator GetEndList();

であるため、const メソッドである必要がありますconst_iteratorlist<Vehicle*>::const_iterator GetEndList() const;

char* GetBaseName() const;
char* GetLocation() const;

const char*変更された名前と場所を処理するようにコードが設定されていないため、これらは を返す必要があります。

list<Vehicle*>::const_iterator FindVehicle(char* id);

繰り返しますが、const メソッドにする必要があります。list<Vehicle*>::const_iterator FindVehicle(char* id) const;

Base::~Base()
{
    delete [] m_name;
    delete [] m_location;
    //m_baseVehicles.clear();
}

m_baseVehicles.clear();とにかくデストラクタの直後に発生するため、必要ありません。ただし、他の場所で参照されていない車両は削除する必要があります。そうしないと、リークが発生します。

軍の破壊者 :

「デストラクタ」。そして、残りはArmyどこですか?

Army::~Army()
{
    list<Base*>::iterator baseIter = m_basesList.begin();
    for (baseIter ; baseIter != m_basesList.end() ; ++baseIter)
        delete (*baseIter);
    m_basesList.clear();
 }  

繰り返しますが、必要ありませんm_basesList.clear();

于 2010-09-27T14:54:13.433 に答える
1

問題はありません。マット・ケインが言ったように、どのようにしてデータが入力されるのでしょうか?

于 2010-09-27T14:46:47.637 に答える
1

ヒープの破損は、セルに割り当てられたメモリよりも多くのデータを割り当てられたヒープ セルにコピーすることによって発生します。ヒープ セルの先頭と末尾には、上書きされた場合よりもデータが含まれており、ヒープの破損として報告されます。

すべてのコードを投稿したわけではなく、投稿したコードに問題は見られませんが、Valgrind などのメモリ ツールを使用して問題を診断することをお勧めします。

于 2010-09-27T14:50:02.797 に答える