2011-10-22 22 views
1

Destructorは、オブジェクトが有効範囲外になるか、または割り当てられたメモリがdelete演算子を使用して割り当て解除されたときに呼び出されることを学びました。C++のデストラクタ呼び出し

#include <iostream> 

using namespace std; 

class point 
{ 
    private: 
     int x_coord; 
     int y_coord; 

    public: 
     point() 
     { 
     x_coord = 0; 
     y_coord = 0; 
     } 

     point(int x, int y) 
     { 
     x_coord = (x > 79 ? 79 : (x < 0 ? 0 : x)); 
     y_coord = (y > 79 ? 79 : (y < 0 ? 0 : y)); 
     } 

     ~point() 
     { 
     cout << "Destructor invoked\n"; 
     } 

     int getx(void) 
     { 
     return x_coord; 
     } 

     int gety(void) 
     { 
     return y_coord; 
     } 
}; 

int main() 
{ 
    point p1; 
    point p2(20, 80); 

    point *p3 = new point; 

    cout << "p1.x = " << p1.getx() << ": p1.y = " << p1.gety()<< "\n"; 
    cout << "p2.x = " << p2.getx() << ": p2.y = " << p2.gety()<< "\n"; 
    cout << "p3->x = " << p3->getx() << ": p3->y = " << p3->gety()<< "\n"; 

    point * p4 = &p1; 
    delete p4; 
    delete p3; 

    return 0; 

} 
  1. P1に割り当てられたメモリは、delete p4を用いて脱割り当てられます。したがって、デストラクタが呼び出されます
  2. delete p3は、次のデストラクタを呼び出します。
  3. p2が範囲外になり、次のデストラクタが呼び出されます。

デストラクタは3回しか呼び出されません。しかし、デストラクタが4回呼び出されるのが分かります。これの理由は何ですか?デストラクタについての私の理解に関して何らかの誤りがありますか

+0

私は 'delete p4'が正しいとは思わない。 – cnicutar

+2

スタックに割り当てられているので 'p1'を' delete 'するべきではありません。 – ObscureRobot

+0

すべてのメソッドを削除した場合、デストラクタ、フィールド、およびそれらのメソッドを呼び出す 'main()'のコードを削除すると、サンプルが大幅に短縮される可能性があります。彼らはあなたの質問には関係ありません。 – ObscureRobot

答えて

4

コードに間違いがあります。 newで作成されていないため、delete p1p4p1を指しています)できません。したがって、プログラムは未定義の動作を呼び出しています。

この場合、p1のデストラクタが最初にdeleteで呼び出され、p1がスコープ外に出てくることがあります。それは他のものでもありえます(他の可能性のある結果はクラッシュです)。

4

p1が範囲外になったときに1回だけでなく、別のオブジェクトではなくp1へのポインタであるdelete p4を呼び出すときも、2度破棄しています。オブジェクトを2回破棄するのは未定義の動作です.btw(スタックオブジェクトを削除する(コメントを参照)と同じです)。

+0

オブジェクトが2回破壊されているのでUBではありませんが、 'new'で返されなかったアドレスが' delete'に渡されているのでUBです。 'p1'はスタック上のオブジェクトであり、フリーストアではありません。 –

+0

@Als:良い点! –

1

p1がスタックに割り当てられていたため、をp4に呼び出したにもかかわらず、現在割り当てられていないp1で削除が呼び出されます。

メモリの割り当てを解除しても、必ずしもそのメモリがゼロになるわけではありません。したがって、デストラクタを再度呼び出してメッセージを出力することは可能です。それとも、爆発するかもしれない。そのため、最後に使用する前にメモリの割り当てを解除しないことが重要です。

0

ポインタp4でのp1の破壊は無効で、デバッグCRTを使用してコンパイルするとランタイムエラーが発生します。

関連する問題