为什么我们需要list_for_each_safe()来删除内核链接列表中的节点? [英] Why do we need list_for_each_safe() in for deleting nodes in kernel linked list?
问题描述
我正在从 list.h 学习如何使用内核链接列表API. a>.
I'm learning how to use the kernel linked-list API from list.h.
我了解到,使用list_del()
删除节点时,需要使用list_for_each_safe()
,而不是使用list_for_each()
.
I learned that I need to use list_for_each_safe()
when deleting nodes off with list_del()
instead of using list_for_each()
.
list_for_each_safe()
的代码:
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
list_for_each()
的代码:
for (pos = (head)->next; pos != (head); pos = pos->next)
我注意到它们都非常相似,只是_safe
版本需要一个额外的参数来用作临时存储"(此处表示为
I notice they both are very similar except that the _safe
version takes an extra argument to be used as 'temporary storage' (stated here, list.h).
我知道何时正确应用该功能,_safe
版本用于删除,普通版本用于访问,但是我很好奇额外的参数如何使其安全"?
I understand when to apply the function correcly, _safe
version for deleting, normal version for accessing, but I'm curious how the extra argument made it 'safe'?
请考虑以下内容,其中我要使用list_for_each_safe()
删除链表中的每个节点:
Consider the following, where I'm deleting every node in a linked list using list_for_each_safe()
:
struct kool_list{
int to;
struct list_head list;
int from;
};
struct kool_list *tmp;
struct list_head *pos, *q;
struct kool_list mylist;
list_for_each_safe(pos, q, &mylist.list){
tmp= list_entry(pos, struct kool_list, list);
printf("freeing item to= %d from= %d\n", tmp->to, tmp->from);
list_del(pos);
free(tmp);
}
给予q
删除帮助如何?
感谢您的帮助!
推荐答案
这是必需的,因为list_del
在内部修改了pos
字段的值.在您的示例中,循环主体甚至释放了pos
占用的内存.假设您将使用不安全的循环版本:
That is necessary because list_del
internally modifies the value of pos
fields. In your example the loop body even frees the memory occupied by pos
. Suppose that you would use unsafe version of the loop:
for (pos = (head)->next; pos != (head); pos = pos->next)
执行循环主体后,pos
指针将无效,从而破坏增量表达式:pos = pos->next
.
After executing the loop body pos
pointer becomes invalid breaking the increment expression: pos = pos->next
.
相反,安全foreach将pos->next
的值预先保存在临时变量中,然后引用后者,而不是取消引用pos
:
As opposite, the safe foreach pre-saves the value of pos->next
in a temporary variable and then refers to the latter instead of dereferencing pos
:
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
这篇关于为什么我们需要list_for_each_safe()来删除内核链接列表中的节点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!