pat*_*seb 8 c linked-list linux-kernel
我正在尝试了解Linux内核链表API.
根据Linux内核链接列表我应该初始化列表,INIT_LIST_HEAD但在这里(Linux内核程序) 建议使用它LIST_HEAD_INIT.
这是我写的一个工作代码,但我不确定我是否以正确的方式做到了.有人可以验证它没问题吗?
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
typedef struct edge_attr {
int d;
struct list_head list;
} edge_attributes_t;
typedef struct edge {
int id;
edge_attributes_t *attributes;
} edge_t;
int main () {
int i;
struct list_head *pos;
edge_attributes_t *elem;
edge_t *a = (edge_t*)malloc(sizeof(edge_t));
a->id = 12;
a->attributes = (edge_attributes_t*) malloc(sizeof(edge_attributes_t));
INIT_LIST_HEAD(&a->attributes->list);
for (i=0; i<5; ++i) {
elem = (edge_attributes_t*)malloc(sizeof(edge_attributes_t));
elem->d = i;
list_add(&elem->list, &a->attributes->list);
}
list_for_each(pos, &(a->attributes->list)) {
elem = list_entry(pos, edge_attributes_t, list);
printf("%d \n", elem->d);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
mpe*_*mpe 23
LIST_HEAD_INIT是一个静态初始化器,INIT_LIST_HEAD是一个函数.他们都将a初始化list_head为空.
如果你是静态声明a list_head,你应该使用LIST_HEAD_INIT,例如:
static struct list_head mylist = LIST_HEAD_INIT(mylist);
Run Code Online (Sandbox Code Playgroud)
您应该使用INIT_LIST_HEAD()动态分配的列表头,通常是另一个结构的一部分.内核源代码中有很多例子.
cni*_*tar 12
快速LXR搜索显示:
#define LIST_HEAD_INIT(name) { &(name), &(name) }
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
Run Code Online (Sandbox Code Playgroud)
因此INIT_LIST_HEAD获取struct list_head *并初始化它,同时LIST_HEAD_INIT以适当的方式返回传递的指针的地址,以用作列表的初始化器:
struct list_head lst1;
/* .... */
INIT_LIST_HEAD(&lst1);
struct list_head lst2 = LIST_HEAD_INIT(lst2);
Run Code Online (Sandbox Code Playgroud)