1

これは、私が持っているいくつかのコードの簡略化されたバージョンです。pointerBinclass Aはポインターに設定されているため、割り当てられたメモリを指すクライアント コードでは、デストラクタで指定されたメモリも削除されたらbeta解放する必要がありますか?pointerBclass A

class A{
   public:
     A(B* beta){
        pointerB = beta;
     }
     ~A(){

      /*
      would deleting pointerB be necessary
      */

      }

     B* pointerB;
};
class B{
   public:
     B();
};

//client code
B* beta = new B();
A* alpha = new A(beta);    

//do stuff
delete beta;
delete alpha;
beta = NULL;
alpha = NULL;
4

7 に答える 7

2

アプリケーションの実行中には、すべてに対してnew1 つだけ存在する必要があります。delete

したがってdelete pointerB、デストラクタで呼び出されるかdelete beta、外部で呼び出されるかは問題ではありません。ここで解放されるのは同じメモリだからです!問題は、A が B のインスタンスを「所有」している (したがって、それが使用するメモリを解放する責任がある) か、または A が B のインスタンスへの参照のみを持っている (たとえば、ベータがまだ使用されているときに削除される) かどうかです。

BUT (Roger が既に指摘したように) と のドキュメントを読むことをお勧めしstd::shared_ptrますstd::unique_ptr。例: http://en.cppreference.com/w/cpp/memoryほとんどの場合、これらをうまく利用できるので、メモリ管理を気にする必要はありません。

于 2013-06-05T06:57:03.207 に答える
1

A:のコンストラクターでの割り当ては、pointerB = beta;新しいメモリを割り当てません。したがって、 のデストラクタを呼び出すときに割り当てを解除する必要はありませんA

ただし、この動作は危険です。

B* beta = new B(); // memory for B is allocated
A alpha( B ); // local instance. A.pointerB points to beta
delete beta; // memory de-allocated
// risky part: alpha.pointerB still points to where beta was allocated 
// BUT THIS MEMORY IS ALREADY FREED!

これについては慎重に考える必要があります。

于 2013-06-05T06:39:09.277 に答える
0

A のデストラクタで削除する必要があります。両方の条件を 1 でテストできるサンプル プログラムがあります。プログラムを実行しても b の値が存在するということは、A のデストラクタでそれを削除する必要があることを意味しますdelete b。 b が空いていることがわかります。

class B;
class A
{
    B * b;

public:
    A(B * obj)
    {
        b = obj;
    }

    ~A()
    {
        //delete b;
    }

};
class B
{
    int value;
public:
    B()
    {
        value = 10;
    }
    ~B()
    {

    }
    int getValue(){return value;}
};

void main()
{
    B *b = new B;
    A * a = new A(b);

    delete a;
    cout<<"B exists: "<<b->getValue();
} 
于 2013-06-05T07:47:23.803 に答える
0

全体的な考え方は、ヒープから何かを割り当てる場合は、割り当てを解除する必要があり、一度だけ実行する必要があり、割り当てが解除された後はメモリにアクセスしないでください。

これを実現するために、通常、割り当てと割り当て解除を同じコンポーネントで行うようにします。たとえば、クラス Foo にメモリを割り当てた場合は、そこでも割り当て解除を行います。ただし、エラーが発生しにくくするための規則にすぎません。割り当て解除が発生することが確実であり、一度だけ発生する限り、すべて問題ありません。

shared_ptr または同様の機能を使用することも、この動作を保証する方法です。

あなたの特定の例に戻ると、A で割り当て解除を行う必要があるかどうかはわかりません。私が言えることは、delete betaあなたが既に行ったようにmain()、両方で割り当て解除を行うAmain()問題になるということです。

割り当てを解除するAか、呼び出し元に任せるかは、設計によって異なります。

于 2013-06-05T06:47:55.197 に答える
0

例は次のように簡略化できます。

struct A{};

int main()
{
  A* wtf= new A;
  A* omg= wtf;
  delete wtf;
}

正しいので、これは次のとおりです。

struct A{};

int main()
{
  A* wtf= new A;
  A* omg= wtf;
  delete omg;
}

両方を削除すると二重削除エラーになるため、次のようにしないでください。

delete omg;
delete wtf;

両方のポインターが指している同じメモリの割り当てを 2 回解除しようとすることになります。

于 2013-06-05T06:37:29.963 に答える