2016-11-29 15 views
1

私はC++を使い始めました。これまでのオブジェクト指向プログラミングの経験がないので、概念は難しいです。私は組み込みの配列とコンストラクタ/デストラクタを学習していますが、私は頭を抱くことができないというエラーが発生しました。ここでは、皆さんにコードを示します。コンストラクタが呼び出されず、 "解放中のポインタが割り当てられませんでした"エラー

クラス定義が

class arraysClass{ 

public: 

    int size1; 
    int size2; 

    int **frequencies; 

    arraysClass(int size1, int size2){ 
     cout << "Constructor: size1&size2 " << size1 << " " << size2 << endl; 
     frequencies = new int*[size1+1]; 
     for (int i=0; i<=size1; i++){ 
      frequencies[i] = new int[size2+1]; 
     } 
    } 

    //Destructor 
    ~arraysClass() 
    { 
     cout << "Destructor: size1&size2 " << size1 << " " << size2 << endl; 
     for (int i=0; i<=size1; i++){ 
      delete [] frequencies[i]; 
     } 
     delete [] frequencies; 

    } 
}; 

、ここでは結果が

コンストラクタであると私は何を得る私の主な機能

int main() 
{ 
    int size1 = 20; 
    int size2 = 30; 
    arraysClass arrays1(size1, size2); 

    arraysClass arrays2 = arrays1; 

    arrays2.size1 = size1; 
    arrays2.size2 = size2; 

    return 1; 
} 

で行く:SIZE1 & size2に20 30

Destr uctor:SIZE1 & size2に20 30

デストラクタ:SIZE1 & size2に0

のa.out(41138,0x7fff75694000)はmalloc:***オブジェクト0x7fa2eac032d0のエラー:ポインタが解放され、割り当てられていなかった

変わったことは、クラスオブジェクトの2番目のインスタンスが明確に存在するときにコンストラクタが1回だけ呼び出されたことです。私はコピーコンストラクタを作ったり、演算子=関数をオーバーロードしたりしていないので、このような状況をどうすればいいかわかりません。

誰かが絶望的な大学生を助ける気に?ありがとう!

+1

暗黙のコピーコンストラクタが呼び出され、2番目のインスタンスがコピーされたポインタを再度削除しようとしました。 –

+1

また、 'for ... i <= size1'を使った' new int * [size1 + 1] 'は、C++の理想的なものではなく、コードの整合性がとれなくなります。実際、デストラクタで 'size1'に依存しているので、' size1'を変更するとクラッシュする可能性があります。すべてのクラスメンバーを非公開にし、 'size'値を不変にする必要があります。 – Dai

+0

@πάνταῥεyourあなたのリードをありがとう。私はそのテーマについていくつかの検索をしましたが、コピーコンストラクタがどのように動作するかについてはあまりにもあいまいです。これは、 'array1'と' arrays2'の両方が同じオブジェクトを指していることを意味しますか?これは、暗黙のコピーコンストラクタがユーザ定義のクラスに対して行うことになっていますか?なぜ私はこのようなエラーメッセージが出るのか説明してくれるはずです。 – Byng

答えて

2

arraysClass arrays2 = arrays1;デフォルトコピーコンストラクタが呼び出され、メンバint **frequenciesarrays2にコピーされました。このキャッチは、いわゆる浅いコピーです。つまり、ポインタ値のみがコピーされ、両方のポインタが同じメモリを指しています。 main関数の終わりに

、両方arrays1arrays2は破壊され、デストラクタ、int **frequenciesに(覚えて、それらが同じ場所を指している)を2回削除しました。そして、既に削除されたポインタを削除することは未定義の動作なので、最初の削除はうまくいく、2番目のプログラムはクラッシュしています。

ここでの修正は、コピーコンストラクタでディープコピーを作成し、オーバーロードされたoperator=です。 コピーコンストラクタの例:

arraysClass(const arraysClass& rhs) { 
    cout << "Copy Constructor" << endl; 
    size1 = rhs.size1; 
    size2 = rhs.size2; 
    frequencies = new int*[size1+1]; 
    for (int i=0; i<=size1; i++){ 
     frequencies[i] = new int[size2 + 1]; 
     memcpy(frequencies[i], rhs.frequencies[i], rhs.size2 + 1) 
    } 
} 
+0

うわー、これは私が心に留めていた質問に正確に答えます。ありがとう! – Byng

関連する問題