-1
class matrix{
    private:
        int n, *wsk;
        friend istream & operator>>(istream&,matrix&);
        friend ostream & operator<<(ostream&,matrix&);
    public:
        matrix(){
            wsk=0;
            n=0;        
        }
        matrix(const matrix &mat){
            this->n=mat.n;
            if (wsk!=0) delete []wsk;
            this->wsk=new int [this->n*this->n];
            for (int i=0;i<n*n;i++)
                wsk[i]=mat.wsk[i];

        }

        ~matrix(){
            if (this->wsk!=0) delete[]this->wsk;
        }

        const matrix & operator=(const matrix &mat){
            if(&mat==this) return *this;
            if (this->wsk!=0) delete [] this->wsk;
            n=mat.n;
            this->wsk=new int [n*n];
            for (int i=0;i<mat.n*mat.n;i++)
                this->wsk[i]=mat.wsk[i];
            return *this;   
    } 
};


istream & operator>>(istream &str, matrix& mat){

    str >> mat.n;
    if (mat.n>0) {
        if (mat.wsk != 0) delete[]mat.wsk;
        mat.wsk= new int [mat.n*mat.n];
        for (int i=0;i<mat.n*mat.n;i++)
            str >> mat.wsk[i];
    }

    return str;
}

ostream & operator<<(ostream &str, matrix& mat){
    if (mat.wsk!=0){
        for (int i=0;i<mat.n*mat.n;i++){
            str << mat.wsk[i] << " ";
            if ((i+1)%mat.n==0) str << endl;
        }
    }
    return str;
}

メインで 2 つの行列を作成しようとすると、最初の次元が 2 番目の次元よりも低くなり、ダブル フリーが発生します。両方の行列の次元が同じ場合、または最初の行列の次元が 2 番目の行列よりも大きい場合、問題はありません。誰かがコードを見て、何が問題なのか教えてくれるでしょうか?

編集:メイン:

int main(){
    matrix mac, a, b;
    cout << "Put number of dimensions and numbers in matrix ";  
    cin >> mac;
    cout << mac;
    cin >> a;   
    cout << a;
    mac.~matrix();
    return 0;
}
4

2 に答える 2

2

私が見るエラーの 1 つは、コピー コンストラクターで、割り当てられていないメモリを削除していることです。

 this->n=mat.n;
 if (wsk!=0) delete []wsk;

非 NULL をチェックしても役に立ちません。そのポインターには null 以外のガベージ値が含まれている可能性がありdelete[]、ガベージ ポインターを使用して呼び出しています。その行をコピー コンストラクターから完全に削除するだけです。

次に、代入演算子に問題があります。

  const matrix & operator=(const matrix &mat){
            if(&mat==this) return *this;

            // you've destroyed your data here
            if (this->wsk!=0) delete [] this->wsk;

            // you've changed one of your members here
            n=mat.n;

            // what if the line below throws a `std::bad_alloc` exception?
            this->wsk=new int [n*n];

コメントは問題を説明しています。データを削除したため、new[]後で失敗した場合に回復する方法がありません。

あなたも戻ってきconstます。これは、代入演算子が const オブジェクトを返すことは正統ではありません。

代入演算子を記述するより良い方法は次のとおりです。

  #include <algorithm>
  //...
  matrix & operator=(matrix mat)
  {
     std::swap(n, mat.n);
     std::swap(wsk, mat.wsk);
     return *this;
  }

これは、作業コピーのコンストラクタとデストラクタがあれば、動作することが保証されています。ここcopy/swapではイディオムが使われています。

deleteまた、またはを発行するときにヌル ポインターをチェックする必要はありませんdelete[]。したがって、デストラクタは次のようになります。

~matrix(){ delete[]this->wsk; }

編集:main関数でこれを行っています:

mac.~matrix();

デストラクタを明示的に呼び出しています。では、macオブジェクトが範囲外になるとどうなるでしょうか? デストラクタが自動的に再度呼び出されるため、二重削除エラーが発生します。

からこの行を削除しmainます。オブジェクトのデストラクタが自動的に呼び出されます。

于 2015-03-16T17:21:50.740 に答える
0

私には、delete[] は配列のすべての要素に対してデストラクタを呼び出そうとし、ポインタを破棄するようです。ダブルフリーエラーが発生する可能性があります。

交換してみましたか

int *foo=new int[n*m]

古いCのmallocと?

int *foo;
foo=(int*)malloc(n*m*sizeof(int));

この方法では、delete[] の代わりに delete を使用できます。これがうまくいくことを願っています。

楽しんで、私に知らせてください

彼女

于 2015-03-16T17:57:41.230 に答える