• ベストアンサー

多重delete

最近デバッグをしていて気づいたのですが、引数がクラスのときはコンストラクタが呼び出されないようなのですが、そうするとデストラクタだけ余分に呼び出されてしまいます。NULLを入れるというのも検討しましたが、もし忘れたときのことも考えると、ほかに良い方法がないものかと思いました。 コード例 class Test{ public: void Compare(class Data Data1,class Data Data2); }; class Data{ private: int *Data; public: Data(){Data=new int[10];} ~Data(){delete[] Data;} }; 上記のようなコードで、Compareを呼び出したときはDataのコンストラクタは呼ばれていませんが、Compareを抜けたときにはデストラクタが呼ばれているようです。 勉強も兼ねて、vectorの代わりになるものを作っていたのですが、どうやら同じポインタにdeleteが複数回呼ばれているようで、エラーが出てしまいます。 もし良い解決策が分かる方いましたら、回答よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Yanch
  • ベストアンサー率50% (114/225)
回答No.1

たぶん、デフォルトの「コピーコンストラクタ」が呼び出されているのじゃないかな。 動作を制御したいなら、「コピーコンストラクタ」と「代入演算子」も、 用意して上げると良いかと思います。

mentalplus
質問者

お礼

多くの方から回答いただきましたが、コピーコンストラクタで解決することにしました。 ありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (4)

回答No.5

本質的な問題は、メンバにポインタがあって、その実体をコンストラクタで確保しているということです。 そもそも、確保する量が、int[10] と固定であるなら、単純に配列で確保すべきですが、vector の練習ということで、これは、将来的に、動的な確保になるのでしょう。 さて、そうすると、引数として呼ばれた場合、(既に回答にあるように)デフォルトのコピーコンストラクタが呼ばれます。 これは、メンバの特性を考えずに、単純に「値」をコピーします。 このため、Data の中身が確保されずに、単純にポインタがコピーされているということになります。 解決策のひとつは、デストラクタで、 ~Data() {delete[] Date; Data = 0;} とすることですが、これをすると、Compare を抜けた後、その引数になっていたオブジェクトの Data も一緒に破棄されます(同じポインタなので) 2番目の解決策は、コピーコンストラクタを定義する方法で、この中で、 Date を「確保して、代入」すれば、いいでしょう。 さらに、(これも回答にあるように)ポインタや、参照で渡すというのも いい解決です。 この場合は、Compare() を抜けるときにデストラクタが呼び出されないことになります。 あと、(メンバーの) Data が、配列として定義されている場合には、配列(というか、ポインタではなくて実体)のほうがコピーされるので、このような問題は発生しません。

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

「それぞれの内容を読むだけで、書くことはしない」なら const をつけてあげるのがよりよいかと>#3. Boost の shared_array は反則?

すると、全ての回答が全文表示されます。
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

void Compare(class Data Data1,class Data Data2); が値渡しになっているので、コピーコンストラクタを使ってData1,Data2のコピーが作られています。定義されていないので、浅いコピーを行います。 深いコピーを行うコピーコンストラクタを定義するのも一つの方法です。 もう一つは、コピーを作らないことです。 Compareと言う関数名から、比較を行うものだと思います。それぞれの内容を読むだけで、書くことはしないでしょう。それならば void Compare(class Data &Data1,class Data &Data2); と参照渡しにするとか void Compare(class Data *Data1,class Data *Data2); とポインタを渡すようにしていも問題ないでしょう。

すると、全ての回答が全文表示されます。
  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.2

Compareの引数は参照では駄目なのでしょうか? そうすればデストラクタも走らないような。

すると、全ての回答が全文表示されます。

関連するQ&A