0

何らかの理由で、Update クラスにデストラクタを使用すると、デバッグ アサーションの失敗メッセージが表示されます...

簡潔にするために一部のコードを省略した Update クラスを次に示します。ヘッダーファイルに配置:

using namespace std;

class Update
{
private:
    int day, month, year;
static const int FIELD_SIZE = 3, DEFAULT_DAY = 12, DEFAULT_MONTH = 12,
    DEFAULT_YEAR = 1999, DAYS_IN_MONTH = 30, MONTHS_IN_YEAR = 12, DAYS_IN_YEAR = 365;

int * date;

public:
static int dateUpdate;

Update(int D, int M, int Y)
{
    day = D;
    if (day < 1 || day > DAYS_IN_MONTH)
        day = DEFAULT_DAY;
    month = M;
    if (month < 1 || month > MONTHS_IN_YEAR)
        month = DEFAULT_MONTH;
    year = Y;
    if (year < 1)
        year = DEFAULT_YEAR;

    date = new int [FIELD_SIZE];
    date[0] = day, date[1] = month, date[2] = year;

    dateUpdate++;
}

~Update()
{
    delete [] date;

    dateUpdate--;
}

};

そして、これがcppファイルの私のテスタークラスです:

#include <iostream>
#include "Update.h"

int Update::dateUpdate = 0;

int main()
{
Update u1(29, 12, 2000);
u1.Update::~Update();

return 0;
}

デバッグ アサーションの失敗に関する他の質問を読みましたが、デバッグ アサーションの失敗はさまざまな方法で発生する可能性があることがわかります。その結果、自分のコードにエラー メッセージが表示される理由についてほとんど手がかりがありません... 現時点で疑うように、デストラクタに何か問題がありますか? 事前に助けてくれてありがとう!

4

2 に答える 2

2

問題は、デストラクタを明示的に呼び出しているためです。

u1.Update::~Update();

この方法で 2 回呼び出され、未定義の動作が発生します。delete [] date; だと思います。は 2 回呼び出され、2 回目はすでに解放されたメモリに対して呼び出されます。

コードのもう 1 つの問題は、配列にベア ポインターを使用していることです。

int * date;

これは、実際には C++ での非常に低レベルのプログラミング スタイルであり、多くの問題を引き起こす可能性があります。Update クラスがコピーされるときに新しい日付配列を割り当てるクラス コピー コンストラクターと代入演算子 (*) を実装する必要があります。そうしないと、複数の日付ポインターの削除で再び問題が発生します。

最良の方法は、次のようなベクトルを使用することです

std::vector<int> date;

(*) ここで適用される 3 の規則 (または C++11 以降の 5 の規則) が説明されている良いリンクだと思います: Rule-of-Three は Rule-of-Five with C++11 になりますか?

于 2013-05-05T19:38:40.523 に答える