unique_ptrを使用したリンクリストのポップメソッド
私はを使用unique_ptr
して単一リンクリストの実装を見ていますhttps://solarianprogrammer.com/2019/02/22/cpp-17-implementing-singly-linked-list-smart-pointers/。私の質問は次の方法に関するものです。
3 struct List {
4 List() : head{nullptr} {};
5
6 // ...
7
8 void pop() {
9 if(head == nullptr) {
10 return;
11 }
12
13 std::unique_ptr<Node> temp = std::move(head);
14 head = std::move(temp->next);
15 }
16
17 // ...
18 };
なぜここで一時的なものが必要なのか疑問に思いますか?なぜあなたは単にすることができなかったのですhead = std::move(head->next)
か?これは、メモリリークが発生するためですか?ときにhead
再割り当てされ、んunique_ptr
、自動的にそれがポイントの現在のメモリを解放?
私は、スマートポインタがメモリリークからの確実な証拠であるという印象を受けました。この場合、オリジナルをhead
指すスマートポインタがなくなるため、オリジナルのメモリリークが発生する可能性がありますか?
回答
なぜここで一時的なものが必要なのか疑問に思いますか?
本当に必要というわけではありませんが、使うのも悪くありません。
なぜあなたは単にすることができなかったのです
head = std::move(head->next)
か?これは、メモリリークが発生するためですか?
あなたはできる。この例ではリークはありません。
ときに
head
再割り当てされ、んunique_ptr
、自動的にそれがポイントの現在のメモリを解放?
はい。ただし、delete
新しいポインタの所有権が最初に譲渡されるまで、古いポインタは'dされません。cppreferenceごと:
https://en.cppreference.com/w/cpp/memory/unique_ptr/operator%3D
を呼び出した後、fromを割り当てることにより、所有権をから
r
に転送します。*this
reset(r.release())
get_deleter()
std::forward<E>(r.get_deleter())
https://en.cppreference.com/w/cpp/memory/unique_ptr/reset
管理対象オブジェクトを置き換えます。
を指定すると
current_ptr
、によって管理されていたポインタ*this
は、次のアクションをこの順序で実行します。
- 現在のポインタのコピーを保存します
old_ptr = current_ptr
- 現在のポインタを引数で上書きします
current_ptr = ptr
- 古いポインタが空でない場合は、以前に管理されていたオブジェクトを削除します
if(old_ptr) get_deleter()(old_ptr)
。
そう:
temp
が使用されている場合、の古いノードへのポインタは、head
最初にtemp
そのmoveコンストラクタを介して移動され、head
を保持するようにリセットされますnullptr
。次に、そのポインタhead.operator=
を呼び出しnext.release()
て取得します。そして、temp
スコープ外になり、delete
'古いノードになります。
temp
が使用されていない場合は、head.operator=
を呼び出しnext.release()
、古いポインタを保存して、解放されたポインタに置き換えてからdelete
、保存されたポインタに置き換えます。
どちらの方法でも漏れはありません。
私は、スマートポインタがメモリリークからの確実な証拠であるという印象を受けました。
適切に使用すれば、はい。
この場合、オリジナルを
head
指すスマートポインタがなくなるため、オリジナルのメモリリークが発生する可能性がありますか?
unique_ptr
古いノードを参照しているので、pop()
終了しtemp
て破棄されるまでリークはありませんdelete
。 '古いノードを使用します。temp
省略された場合でも、next
ポインタの所有権が譲渡された後、古いノードは適切に破棄されます。