2012-04-28 18 views
1

ここでは、+操作で使用できるクラスの例を示します。この追加クラスはメモリリークの原因になりますか?

class A 
{ 
public: 
    int *array; 

    A() 
    { 
     array = new int[10]; 
    } 

    ~A() 
    { 
     delete[] array; 
    } 

    A operator+ (const A &b) 
    { 
     A c; 
     for(int i=0; i<10; i++) 
     c.array[i] += array[i] + b.array[i]; 
     return c; 
    } 
}; 

int main() 
{ 
    A a,b,c,d; 

    /* puts some random numbers into the arrays of b,c and d */ 
    a = b+c+d; 
} 

ab+c+dかどうかの結果をコピーする前に、デストラクタを実行しますか?そうでない場合、どのようにメモリが漏れていないことを確認しますか?

+演算子オーバーロードは、このようにしてオペランドが変更されないように設計されています。

+0

[あなたの前の質問](http://stackoverflow.com/q/10360232/78845)の回答が間違っていましたか?なぜ 'std :: vector'ではなく' new int [10] 'を使用していますか? – Johnsyweb

+0

これは理解しようとする例であると仮定していますが、これが本当のコードであれば、 'int array [10];'を定義し、適切な削除を心配する必要はありません。 – Corbin

+0

@Johnsyweb答えは素晴らしかったですが、これは単なる例であり、あまり考えなくてもスケッチしました。この例は、他の回答に対する私の見解を示すものではありません。 –

答えて

9

等価演算子をAに追加する必要があります。また、likely want to create a copy constructorになります。

aがb + c + dからの戻り値になると、ポインタがaになり、delete[]が呼び出されずに上書きされます。 operator =を作成してarrayを削除する必要があります。

オペレータの例は、=以下の通りです:

A& operator=(A const& a) 
{ 
    if (&a != this) { 
     int* tmp = this->array; 
     this->array = new int[10]; 
     //copy a.array to this->array 
     delete[] tmp; 
    } 
    return *this; 
} 

あなたはoperator=に新しいしている場合には微妙なの多くは、この中にあります。

特に

それは書くために完全に有効だから、athisに等しいか否かのチェックが必要です:

A a; 
a = a; 

これは無意味なコピーを引き起こす、とoperator=のほとんどの場合、バグの原因となります。

他の繊細さは、1つ以上のコーディングスタイル(非常に広範な標準ですが)よりも要件のほうが少なくなります。動的に割り当てられたものをコピーするときは、リリースする前に常に割り当ててコピーしたいと思っています。そうすれば、newが例外を投げた場合(または何かが失敗した場合)、オブジェクトは安定した状態になりますが、新しい期待値の代わりに古いデータが使用されます。

+0

素晴らしいチップをありがとう! –

+1

も参照してください:http://stackoverflow.com/q/3279543/78845 – Johnsyweb

2

これはメモリリークの原因になりますか?

はい、そうです。コピーコンストラクタと代入演算子を追加するのを忘れてしまった。 See Rule of Three

int*の代わりにA::arraystd::vector<int>を使用することもできます。この場合、コピーコンストラクタ/代入演算子(destrcutorで扱わなければならない他のものを追加しない限り)を心配する必要はありません。

関連する問題