使用unique_ptr的链表pop方法
Pop method of linked list using unique_ptr
我正在查看在 https://solarianprogrammer.com/2019/02/22/cpp-17-implementing-singly-linked-list-smart-pointers/ 上使用 unique_ptr
的单向链表的实现。我的问题与以下方法有关:
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
可能存在内存泄漏,因为不再有指向它的智能指针?
I am wondering why the temporary is needed here?
并不是真的需要,但也不好使用。
Why couldn't you simply do head = std::move(head->next)
? Is this because it will result in a memory leak?
可以。本例不会有泄漏。
When head
is reassigned, does unique_ptr
automatically free the current memory it's pointing to?
是的。但是,在首先转移新指针的所有权之前,旧指针不会 delete
'。根据 cppreference:
https://en.cppreference.com/w/cpp/memory/unique_ptr/operator%3D
Transfers ownership from r
to *this
as if by calling reset(r.release())
followed by an assignment of get_deleter()
from std::forward<E>(r.get_deleter())
.
https://en.cppreference.com/w/cpp/memory/unique_ptr/reset
Replaces the managed object.
Given current_ptr
, the pointer that was managed by *this
, performs the following actions, in this order:
- Saves a copy of the current pointer
old_ptr = current_ptr
- Overwrites the current pointer with the argument
current_ptr = ptr
- If the old pointer was non-empty, deletes the previously managed object
if(old_ptr) get_deleter()(old_ptr)
.
所以:
在使用temp
的情况下,指向head
中旧节点的指针将首先通过其移动构造函数移动到temp
,重置head
持有一个nullptr
。然后 head.operator=
将调用 next.release()
并获取该指针。然后 temp
将超出范围,delete
'ing 旧节点。
在没有使用temp
的情况下,head.operator=
会调用next.release()
,保存它的旧指针并用释放的指针替换,然后delete
保存的指针。
两边都没有泄漏。
I was under the impression that smart pointers are fool proof from memory leaks.
如果使用得当,是的。
It seems in this case there might be a memory leak for the original head
because there would no longer be a smart pointer pointing to it?
没有泄漏,因为总是有一个 unique_ptr
引用旧节点,直到 pop()
退出并且 temp
被销毁,delete
'ing旧节点。即使 temp
被省略,旧节点在其 next
指针的所有权转移后仍会被正确销毁。
我正在查看在 https://solarianprogrammer.com/2019/02/22/cpp-17-implementing-singly-linked-list-smart-pointers/ 上使用 unique_ptr
的单向链表的实现。我的问题与以下方法有关:
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
可能存在内存泄漏,因为不再有指向它的智能指针?
I am wondering why the temporary is needed here?
并不是真的需要,但也不好使用。
Why couldn't you simply do
head = std::move(head->next)
? Is this because it will result in a memory leak?
可以。本例不会有泄漏。
When
head
is reassigned, doesunique_ptr
automatically free the current memory it's pointing to?
是的。但是,在首先转移新指针的所有权之前,旧指针不会 delete
'。根据 cppreference:
https://en.cppreference.com/w/cpp/memory/unique_ptr/operator%3D
Transfers ownership from
r
to*this
as if by callingreset(r.release())
followed by an assignment ofget_deleter()
fromstd::forward<E>(r.get_deleter())
.
https://en.cppreference.com/w/cpp/memory/unique_ptr/reset
Replaces the managed object.
Given
current_ptr
, the pointer that was managed by*this
, performs the following actions, in this order:
- Saves a copy of the current pointer
old_ptr = current_ptr
- Overwrites the current pointer with the argument
current_ptr = ptr
- If the old pointer was non-empty, deletes the previously managed object
if(old_ptr) get_deleter()(old_ptr)
.
所以:
在使用temp
的情况下,指向head
中旧节点的指针将首先通过其移动构造函数移动到temp
,重置head
持有一个nullptr
。然后 head.operator=
将调用 next.release()
并获取该指针。然后 temp
将超出范围,delete
'ing 旧节点。
在没有使用temp
的情况下,head.operator=
会调用next.release()
,保存它的旧指针并用释放的指针替换,然后delete
保存的指针。
两边都没有泄漏。
I was under the impression that smart pointers are fool proof from memory leaks.
如果使用得当,是的。
It seems in this case there might be a memory leak for the original
head
because there would no longer be a smart pointer pointing to it?
没有泄漏,因为总是有一个 unique_ptr
引用旧节点,直到 pop()
退出并且 temp
被销毁,delete
'ing旧节点。即使 temp
被省略,旧节点在其 next
指针的所有权转移后仍会被正确销毁。