0

私は次のアプリ構造を持っています:

/// CLASS VIEW3D.h
class View3D;
typedef boost::shared_ptr<View3D>     ViewSP;
class View3D
{

public:
   View3D(void);


    };

/// CLASS SCREENQUAD.h

 class ScreenQuad
{
public:
    ScreenQuad(ViewSP view);

    ~ScreenQuad(void);
    protected:
    ViewSP _viewSP;




};
/// CLASS VIEW3D.cpp
  View3D::Init(ViewSP view)

{

    _screenQuadSP=new ScreenQuad(view);

}

///クラスSCREENQUAD.cpp

 ScreenQuad::ScreenQuad(ViewSP view):

    _viewSP(view)           
{
    assert(_viewSP);

}

ここで、クラスの参照を共有ポインターの形式でクラスに渡し、それをグローバル変数に保持Aします。アプリが撃墜されたとき、私はこれを取得しています:BA_SP

HEAP:   Free Heap block 2837920 modified at 2837b5c after it was freed

実行をデバッグした後、クラスAデストラクタが呼び出された後、クラスのデストラクタが実行されると再び呼び出されることがわかりましたB。したがって、ブーストは、にカプセル化されたポインタのアドレスでメモリを解放しようとしていると思います_A_ref。注意点:破壊の順序は、A最初にクラス、次にBクラスです。

どうすれば回避できますか?shared_ptrrefカウントを保持し、すでにリリースされているオブジェクトのデストラクタをトリガーしないようにする必要がありますか?

4

1 に答える 1

3

あなたのコードはまだ不完全すぎて問題を示していますが、そのようなエラーのいくつかの一般的な原因を考えることができます。

  • deleteView3Dインスタンスをどこかに明示的に指定します。そうしないでください、shared_ptr意志。オブジェクトが不要になった場合は、を呼び出すことができますptr.reset()。これにより、参照カウントが減り、必要に応じて削除されます。shared_ptr(これは、たとえばデストラクタでaが破棄されると自動的に発生しますScreenQuad。その場合、明示的に行う必要はありません。)

  • 同じオブジェクトに対して誤って複数の参照カウンターを作成しました。shared_ptr生のポインタからを作成する場所は1つだけView3D*、つまりオブジェクトが作成される場所と同じ場所にある必要があります。他の場所では、他の共有(または弱い)ポインターから共有ポインターを作成する必要があります。そうしないと、複数の参照カウンターが作成され、オブジェクトが既に解放されている場合でも、これらの各カウンターが最終的にオブジェクトを削除しようとします。

  • shared_ptrスタック上のオブジェクトにを作成しました。delete基本的に、これはスタックに割り当てられたオブジェクトを呼び出すのと同じ問題です。

これは、自分でエラーを見つけるのに役立つ場合があります。そうでない場合は、実際にさらにコードを投稿する必要があります。これまでに示したスニペットでは、これが何も起こらないことがわかります。

于 2013-03-03T13:41:06.347 に答える