c/c++语言开发共享为什么我们需要list_for_each_safe()来删除内核链表中的节点?

我正在学习如何使用list.h中的内核链表API。

我了解到,当使用list_del()而不是使用list_for_each()删除节点时,我需要使用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版本需要一个额外的参数用作’临时存储’(这里说明, list.h )。

我知道何时应用相应的function, _safe版本用于删除,正常版本用于访问,但我很好奇额外的参数如何使其“安全”?

请考虑以下内容,我使用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= %dn", tmp->to, tmp->from); list_del(pos); free(tmp); } 

如何帮助删除?

谢谢你的帮助!

    这是必要的,因为list_del内部修改了pos字段的值。 在你的例子中,循环体甚至可以释放pos占用的内存。 假设您将使用不安全的循环版本:

     for (pos = (head)->next; pos != (head); pos = pos->next) 

    执行循环体后, pos指针变为无效,打破增量表达式: pos = pos->next

    相反,安全foreach预先将pos->next的值保存在临时变量中,然后引用后者而不是取消引用pos

     for (pos = (head)->next, n = pos->next; pos != (head);  pos = n, n = pos->next) 

     pos = start; del(pos); pos = pos->next; 

    而不是

     pos = start; n = pos->next; del(pos); pos = n; 

    如果del()是free()和memset(),则pos-> next是未定义的

    需要了解更多c/c++开发分享为什么我们需要list_for_each_safe()来删除内核链表中的节点?,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)

      以上就是c/c++开发分享为什么我们需要list_for_each_safe()来删除内核链表中的节点?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注(计算机技术网)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请点击右边联系管理员删除。

      如若转载,请注明出处:https://www.ctvol.com/c-cdevelopment/979065.html

      (0)
      上一篇 2021年12月12日
      下一篇 2021年12月12日

      精彩推荐