web-dev-qa-db-ja.com

unique_ptr :: release()はデストラクタを呼び出しますか?

このコードは正しいですか?

auto v =  make_unique<int>(12);
v.release();     // is this possible?

生のポインタのdeleteと同等ですか?

53
Zeukis

いいえ、コードによりメモリリークが発生します。 releaseは、管理対象オブジェクトの所有権を解放するために使用されますwithout削除:

auto v = make_unique<int>(12);  // manages the object
int * raw = v.release();        // pointer to no-longer-managed object
delete raw;                     // needs manual deletion

セーフティネットなしで生のメモリをジャグリングする正当な理由がない限り、これを行わないでください。

オブジェクトを削除するには、resetを使用します。

auto v = make_unique<int>(12);  // manages the object
v.reset();                      // delete the object, leaving v empty
114
Mike Seymour

このコードは正しいですか?

いいえ。std::unique_ptr<>::reset()を使用して、内部rawポインターを削除します。

_auto v =  std::make_unique<int>(12);
v.reset(); // deletes the raw pointer
_

その後、std::unique_ptr<>::get()nullptrを返します(std::unique_ptr<>::reset()nullptr以外のパラメーターを指定した場合を除く)。

22
Johann Gerell

このコードは正しいですか?

そうではなく、リークします。

release()は、呼び出し元のコードが、_unique_ptr_が呼び出されるまで保持していたメモリの所有権を取り戻すだけです。 release()によって返されるポインタを割り当てないと、リークが発生します。

_unique_ptr_の明示的な削除はreset()になります。ただし、_unique_ptr_が存在するため、保持するメモリを直接管理する必要はありません。つまり、_unique_ptr_はスコープから外れると、元の生のポインターを安全に削除することを知っておく必要があります。

したがって、自動メモリ管理オブジェクトに対して手動メモリ管理を実行する非常に良い理由が必要です。

17
JBL

releaseは、何にも割り当てないため、生のポインタをリークします。

それは次のようなものに使用されることを意図しています

int* x = v.release();

つまり、vはそのポインターの有効期間を管理しなくなり、生のポインターの所有権をxに委任します。何も割り当てずにreleaseだけを使用すると、生のポインターがリークします。

11
CoryKramer

任意の型には少し注意が必要です。

  unique_ptr<Foo> v = get_me_some_foo();  // manages the object
  Foo * raw = v.release();        // pointer to no-longer-managed object
  delete raw;

ほぼ正しいです。

  unique_ptr<Foo> v = get_me_some_foo();  // manages the object
  Foo * ptr = v.release();        // pointer to no-longer-managed object
  v.get_deleter() ( ptr );

これはすべての状況で正しいでしょう。 Foo型で定義されたカスタム削除機能がある場合がありますが、unique_ptrオブジェクトによって返される削除機能を使用することは、すべての場合に適しています。

2
MichaelMoser