0

仮定する:

struct Foo
{
    Obj* pObj;
    Foo() : pObj(NULL);
};

Obj* CreateObj()
{
   //do some stuff and then
   return new Obj; //obj is a class
}

int main()
{
   Foo foo;
   foo.pObj = CreateObj();
   DoSomeOperationWithTheObj( foo.pObj );
   //suppose foo is a monster that should be 'killed' or deleted now
   delete foo.pObj;
   foo.pObj = NULL;
   //the question is can this pointer be 're-used' now like this:
   foo.pObj = CreateObj(); //create another object
}

ポインターが削除されたので、再利用しても問題ありませんか?

4

5 に答える 5

3

元の質問については、はい、そのようなポインターに再割り当てできます。ポインタはメモリ アドレスだけを保持し、それ以上のものは保持しません。

しかし、実際にはこれを行うべきではありません。このような生のポインターを処理するとバグが発生する可能性があるためです。コードには既にそれらのいくつかがあります。最新の C++ では、この方法をより適切に、心配することなく行うことができます。この (コンパイル可能な) コードから始めるとします。Obj を int に置き換えましたが、それがクラスではなくネイティブ型であるという事実は問題ではありません。

#include <iostream>

struct Foo
{
    int* pObj;
    Foo() : pObj(NULL) {}
};

int* CreateObj()
{
   return new int(42); //obj is a class
}

int main()
{
   Foo foo;
   foo.pObj = CreateObj();
   std::cout << *foo.pObj << std::endl;
   delete foo.pObj;
   foo.pObj = new int(13);
   std::cout << *foo.pObj << std::endl;
   delete foo.pObj;
}

これを次のように変換できます。

#include <iostream>
#include <memory>

struct Foo
{
    std::unique_ptr<int> pObj;
    Foo() : pObj(NULL) {}
};

std::unique_ptr<int> CreateObj()
{
   return std::unique_ptr<int>(new int(42));
}

int main()
{
   Foo foo;
   foo.pObj = CreateObj();
   std::cout << *foo.pObj << std::endl;
   foo.pObj = std::unique_ptr<int>(new int(13));
   std::cout << *foo.pObj << std::endl;
}

主な変更点は、生のポインターを削除してunique_ptrラッパーに置き換えたことです。これにはいくつかの利点があります。

  1. 所有権を明確に述べunique_ptrています。現在のスコープのみが所有できます。createObj はオブジェクトを作成しますが、一時的な (名前のない) オブジェクトを返すunique_ptrことで所有権を解放し、呼び出し元がいつでもオブジェクトを削除できるようにします。これにより、トリッキーなメモリリークが回避されます。
  2. unique_ptrがスコープ外になったとき、またはオーバーライドされたとき (たとえば、代入演算子によって) に、削除は自動的に行われます。
于 2012-10-23T06:33:21.613 に答える
1

はい、ポインタを再利用できます。ポインタは、オブジェクトを参照するための単なる方法です。オブジェクトを削除するので、必要なものにポインタを自由に使用できます。

于 2012-10-23T05:20:57.920 に答える
1

そうすれば間違いなく問題はありません。ポインターは、アドレスの単なるコンテナーです (値を含む変数に類似しています)。

newオブジェクトを割り当て、それにアドレスを返します。delete次に、 d ポインター、「既存の」割り当てオブジェクトを保持するポインター、NULL 保持ポインター、または初期化されていないポインターのいずれであっても、必要な (適切な型の) 任意のポインターに結果アドレスを割り当てることができます。

于 2012-10-23T05:23:18.717 に答える
0

コードですでに行ったように、以前に割り当てられたメモリが最初に割り当て解除されている限り、ポインタを再利用することに問題はありません。

ポインタをdelete使用すると、実際にポインタが指すメモリを解放します。ポインタの値(そのメモリの開始アドレスpointer = NULL)は、またはによって再割り当てするまで変更されません。pointer = new ..

于 2012-10-23T05:58:39.433 に答える
0

ポインタを削除したことがないため、ポインタを再利用できます。Objポインタが指しているを削除しました。ポインタがメモリアドレスを格納していることに注意してください。したがって、intを別の値に変更できるのと同じように、いつでもポインタを変更して、別のメモリアドレスを記憶または指すようにすることができます。また、に対して削除操作を実行する場合、foo.pObj「foo.pObjを削除する」と言っているのではありません。代わりに、「foo.pObjが指しているObjを削除する」と言っています。

foo.pObj問題が発生するのは、操作を実行した後で、ポイントしているオブジェクトに対して何かを行おうとした場合ですdelete

于 2012-10-23T05:59:06.290 に答える