1

私は について学んでおりstd::unique_ptr、それが何を表しているかを理解しようとしています。

を返す関数 (私の制御外) が与えられた場合、各呼び出しが新しいオブジェクトを指す (以前の呼び出しとは異なる) を返すunique_ptrことが暗示/よく理解されていますか?unique_ptr

例として、次のコードは終了時に double-free を生成します。その理由を正しく理解していることを願っていunique_ptrます。したがってunique_ptr、同じメモリ/オブジェクトをカプセル化する 2 つの は、2 番目の破壊時に二重解放を引き起こします。したがって、関数の次の実装は、getUniquePtr()一般的/暗黙的に不合理であると理解されますか?

// main.cpp
#include <memory>
#include <iostream>

std::unique_ptr<int> getUniquePtr() {
  static int* p = new int(42);
  return std::unique_ptr<int>(p);
}

class PtrOwner {
public:
  std::unique_ptr<int> p_;
};

int main( int argc, char* argv[] ) {
  PtrOwner po1;
  PtrOwner po2;
  po1.p_ = getUniquePtr();
  po2.p_ = getUniquePtr();

  return 0;
}
4

2 に答える 2

5

関数が を返した場合、返されたスマート ポインタは、現在他の誰にも管理されていないオブジェクトをstd::unique_ptr<T>指していると想定する必要があります。これは、常に別のオブジェクトを参照しているとは限りません。この規則が守られている限り、ダブルフリーのバグは回避されます。この規則に違反すると、ダブルフリーのバグが発生します。

たとえば、次のような関数が表示された場合:

std::unique_ptr<T> foo(std::unique_ptr<T> arg);

この関数は、潜在的に、状況によっては戻るか、他のポインターstd::move(arg)を破棄して返す可能性があります。arg(それが何をするかを知るには、ドキュメントを読む必要があります)。これは、次のようなことができることを意味します。

auto t = std::make_unique<T>();
t = foo(std::move(t));
t = foo(std::move(t));

この場合、foo同じポインター値が 2 回返される可能性がありますが、これは完全に安全です。この例はばかげているように見えますが、うまくいけば、私の主張が理解できると思います。

于 2020-12-02T20:22:41.723 に答える