3

私は次のクラスを持っています:

class Patient {
public:
    Patient(int x);
    ~Patient();
private:
    int* RP;
};

Patient::Patient(int x) { RP = new int [x]; }
Patient::~Patient() { delete [] RP; }

次のように、スタック上にこのクラスのインスタンスを作成します。

void f() { Patient p(10); }

現在、f()戻ると、「二重の解放または破損」エラーが表示されます。これは、何かが複数回削除されようとしていることを示しています。しかし、なぜそうなるのか理解できません。配列のスペースはヒープ上に作成されます。スペースが割り当てられた内部の関数が返されたからといって、スペースが再利用されるとは思いません。

(キーワードを使用して) ヒープにスペースを割り当てた場合、newそのスペースを再利用する唯一の方法は delete キーワードを使用することだと思いました。ヘルプ!

要求に応じて、ここに実際のコードがあります (簡潔にするために少し省略されています)。

.cpp完全なクラス定義は次のとおりです (複数の.hファイルに分割されていますが、まとめて表示されています)。

class Patient {

public:
    Patient(int numDecisionEpochs);

    ~Patient();

    void recordRP(const int& age, const bool& t);
    void recordBiopsy(const int& age, const int& result);
    void recordPSA(const int& age, const double& level);
    void recordPSA(const int& age);
private:
    int* RP;
    int* Biopsy;
    double* PSA;
};

Patient::Patient(int numDecisionEpochs) {
    RP = new int [numDecisionEpochs];
    Biopsy = new int [numDecisionEpochs];
    PSA = new double [numDecisionEpochs];
}

Patient::~Patient() {
    delete[] RP;
}

void Patient::recordRP(const int& age, const bool& t) {
    if(t)
    RP[age-1] = 1;  // RP either yes (1) or no (0)
    else
    RP[age-1] = 0;
}

void Patient::recordBiopsy(const int& age, const int& result) {
    switch(result)
    {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
        Biopsy[age-1]=result; // only permit results 0,1,2,3,4
        break;
    default:
        cerr << "Invalid biopsy result (" << result << ") at age " << age << "!\n";
    }
}

void Patient::recordPSA(const int& age, const double& level) {
    PSA[age-1] = level; // record PSA volume
}

void Patient::recordPSA(const int& age) {
    PSA[age-1] = -1; // symbol for no screening during epoch
}

次に、上記のクラスを使った関数。次の関数は、クラスから完全に独立して分離されmain()たオブジェクトから直接呼び出され、渡されます。PolicyPatient

void simulate1(Policy& P)
{
    // ...
    Patient patient(260);

    for(int idx=0; idx<(P.size); idx++)
    {
        while(state != 9) // while patient not dead
        {
                // ...
                patient.recordPSA(age,PSA);
                // ...
                patient.recordPSA(age);
                // ...
                patient.recordBiopsy(age,biopsyResult);
                // ...
                patient.recordRP(age,true);
                // ...
                patient.recordRP(age,false);
                // ...

        } // end patient (while loop)

    } // end sample (for loop)

} // end function
4

3 に答える 3

7

三つのルール(またはC ++ 11の場合は5のルール)に違反しています。ポインターのディープコピーを実行するコピーコンストラクターとコピー代入演算子が必要です。もちろん、割り当てる配列のサイズを追跡しないため、2番目のデータメンバーを導入しないとこれは不可能です。

于 2012-04-10T23:34:43.293 に答える
2

これはあなたの質問に直接答えるものではありませんが、std::vector の使用も検討してください。

于 2012-04-10T23:37:35.193 に答える
0

record...年齢をチェックするメソッドには何もありません。したがって、年齢がたまたまあなたの例よりも大きい260か小さい場合は、またはまたはの境界を超えて書き込みます。これは、「二重解放または破損」エラーに直接つながります。0RPBiopsyPSA

于 2012-04-10T23:48:47.010 に答える