list_for_each_safe的实现原理非常巧妙。它通过每次都在遍历过程中保存下一个节点的指针,来保证在对当前节点进行操作之前,链表的结构不会发生变化。这是通过将pos(当前节点)和n(下一个节点)两个指针都先初始化为链表的第一个节点(head)来实现的。在每次迭代中,先提前保存下一个节点的指针继续遍历,然后再使用当前...
执行语句1; 执行语句2,若其值为真,则执行 for 语句中的循环体;若语句2值为假,则结束循环,转到第5步。 执行语句3; 跳转第2步继续执行; 循环结束,执行 for 语句下面的语句。 LIST_FOR_EACH_SAFE的宏定义如下: 1 2 3 #defineLIST_FOR_EACH_SAFE(pos, tmp, head) \ for((pos) = (head)->next, (...
= (head); \ pos = pos->next) 由定义可知,list_del(pos)(将pos的前后指针指向undefined state)panic,list_del_init(pos)(将pos前后指针指向自身)导致死循环。 #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = ...
list_for_each_safe():首先将pos的后指针缓存到n,处理一个流程后再赋回pos,避免了这种情况发生。 因此之遍历链表不删除结点时,可以使用list_for_each(),而当由删除结点操作时,则要使用list_for_each_safe()。 其他带safe的处理也是基于这个原因。
解析 #define list_for_each_safe(cur, tmp, list) \ for (cur = (list)->head.next, \ tmp = (cur)->next; \ cur != &(list)->head; \ cur = tmp, tmp = (tmp)->next)上面这些是宏代码,下面这些是调用这个宏.list_for...反馈 收藏 ...
本文对双向链表进行探讨,介绍的内容是Linux内核中双向链表的经典实现和用法。其中,也会涉及到Linux内核中...
#define list_for_each_entry_safe(pos, n, head, member) ``` 其中,pos是当前遍历的节点的指针,n是下一个节点的指针,head是双链表的头节点指针,member是节点中的list_head成员变量。 它的使用方法如下所示: ```c // 对pos进行操作 // 删除pos节点 kfree(pos); ``` 在这个例子中,我们可以在遍历过...
list_for_each_entry_safe原理 `list_for_each_entry_safe`是Linux内核源码中双向链表的遍历函数,用于遍历链表中的元素。它的原型定义如下: ```c #define list_for_each_entry_safe(pos, n, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member), \...
list_for_each_entry_safe宏是list_for_each_entry宏的变种,它与list_for_each_entry宏完全相同,只是多了一个参数n,用来保存pos参数指向的下一个节点,使得在遍历期间可以安全地修改链表。 以下为list_for_each_entry_safe函数的示例程序,该程序用于将一个链表中的元素都复制到另一个链表中: ...
一、list_for_each_entry_safe基本用法 list_for_each_entry_safe数由C言中的宏定义构成,它有三个参数:pos,n,head。其中,head指向头节点的指针,pos n指向遍历节点的指针,每次循环时,pos是指向当前节点,而n是指向下一个要遍历的节点。 list_for_each_entry_safe数的典型用法如下: struct list_head *head;tt...