2017-04-19 1 views
0

メンバーとして別のオブジェクトへのポインターを持つ型があります。オブジェクト(Demo)が作成されると、コンストラクタ内の他のオブジェクト(Property)が初期化されます。私はこれらのオブジェクトをたくさん持っている場合は、別のものにプロパティを変更するときにヒープスペースを無駄にしたくないので、setPropertyの初期化されたメモリを解放してから、デモのデコンストラクタで再度削除します。その点で何か違うものに設定されています。ただし、これによりコードがクラッシュします。 propertyをリセットしたときに再割り当てするとクラッシュするのはなぜですか?C++ポインターである既定のオブジェクトメンバーを削除する方法

class Property{ }; 


class Demo{ 
    protected: 
      Property *property; 
    public: 
      Demo(){ property = new Property();}; 

      void setProperty(Property *p){ 
        delete property; 
        property = p; 
      }; 

      ~Demo(){ 
        delete property; 
      }; 
}; 

int main(){ 
    Property p = Property(); 
    Demo * d = new Demo(); 

    d->setProperty(&p); 

    delete d; 
} 
+1

「プロパティ」はどこで宣言されていますか?また、 'new'で作成されたものを解放するためにのみ' delete'を使います。 'main()'の 'p'はスタックに割り当てられているので、' Demo ::〜Demo() 'はスタック割り当てオブジェクトを効果的に削除します。これは未定義の動作です。 – cdhowie

+0

これはコンパイルされていない( 'property'は存在しません)という事実の他に、ここではあまりにも多くの誤解があります。なぜあなたは最初に動的割り当てを使用して、祈っているのですか? –

+0

あなたは[ルール3](https://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming))に違反しています。あなたは '新しい。 –

答えて

5

あなたがいないnewによって作成されたオブジェクトのアドレスを渡し、その後deleteにそれをしてみてください。これは未定義の動作です。

最も可能性の高いクラッシュコースの解説は、標準ライブラリでもProperty pが解放されるということです。最初に解放してから、プログラムの最後にもう一度pを解放します。

「修正」は、削除が許可されているオブジェクト、つまりnewによって作成されたオブジェクトを渡すことです。

int main(){ 
    Property *p = new Property(); 
    Demo * d = new Demo(); 

    d->setProperty(p); // Demo is responsible for freeing `p`. 

    delete d; 
} // standard libraries do clean up objects from `main` here 

あなたがしようとしていることをよりよく実装する方法があることにご注意ください。この回答はちょうどクラッシュを説明します。

これは、あなたが自由にすべきかどうかを選択するこのdesingでかなり難しいです。したがって、コードはパラメータの起源に依存します。それはデザインのための赤旗でなければなりません。

3

標準ライブラリで提供されている適切なツールを使用して、すべてのメモリ管理の問題を解決します。

#include <memory> 

class Property{ }; 


class Demo{ 
    protected: 
      std::unique_ptr<Property> property; 
    public: 
      Demo() 
      : property { new Property() } 
      { } 

      void setProperty(std::unique_ptr<Property> p){ 
       property = std::move(p); 
      }; 

    // un-necessary 
    //  ~Demo(){ 
    //    delete property; 
    //  }; 
}; 

int main(){ 
    auto p = std::unique_ptr<Property>(new Property); // or in c++14: = std::make_unique<Property>(); 
    auto d = std::unique_ptr<Demo>(new Demo); // or in c++14: = std::make_unique<Demo>(); 

    d->setProperty(std::move(p)); 

    // no longer necessary 
    // delete d; 
} 
関連する問題