linux 内核链表的替换(list_replace)的解析

假设你已经懂了链表的基本操作。。

函数原型。。

/**
 * list_replace - replace old entry by new one
 * @old : the element to be replaced
 * @new : the new element to insert
 *
 * If @old was empty, it will be overwritten.
 */

static inline void list_replace(struct list_head *old,
                struct list_head *new)
{
    new->next = old->next;
    new->next->prev = new;
    new->prev = old->prev;
    new->prev->next = new;
}

画个图,看看这个究竟要干嘛。

第一步:我们要做什么?

如下图所示,将  new  节点替换 old 节点(看一看成是删除old,在old 的位置插入new节点)

linux 内核链表的替换(list_replace)的解析

 

 

 

第一句:    new->next = old->next; 

如下图所示: new 节点的前驱指针要指向  c(old 的下一个指针)c节点的地址保存在  old->next

new->next = old->next 这句话就相当于 new 节点的前驱指针 指向了 c节点

linux 内核链表的替换(list_replace)的解析

 

 

 第二句: new->next->prev = new;

完成的内容如下图所示:将 c节点指向 new节点。 前面   new->next已经指向了 c节点,所以   new->next->prev:指的是 c节点的 prev。 这句也可以这样写,效果是一样的 : old->next->prev = new

linux 内核链表的替换(list_replace)的解析

 

第三句:new->prev = old->prev;

效果如下图: 将new 指向 old 的前一个节点(A),A节点的地址保存在 old->prev上。

linux 内核链表的替换(list_replace)的解析

 

第四句   new->prev->next = new;

将  A节点的 后驱(next)指针指向 new. A节点的地址 可以通过  new->prev找到 ,所以A节点的后驱指针 new->prev->next = new

完成new 节点的替换 old节点。

linux 内核链表的替换(list_replace)的解析