9

我正在尝试了解 Linux 内核链表 API。

根据Linux Kernel Linked List,我应该初始化列表头,INIT_LIST_HEAD在这里(Linux Kernel Program) 建议使用它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;
}
4

2 回答 2

26

LIST_HEAD_INIT是一个静态初始化器,INIT_LIST_HEAD是一个函数。他们都将 a 初始化list_head为空。

如果您静态声明 a list_head,则应使用LIST_HEAD_INIT,例如:

static struct list_head mylist = LIST_HEAD_INIT(mylist);

您应该使用INIT_LIST_HEAD()动态分配的列表头,通常是另一个结构的一部分。内核源码中有很多例子。

于 2012-04-22T04:21:18.573 回答
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;
}

因此INIT_LIST_HEAD获取 astruct list_head *并对其进行初始化,同时LIST_HEAD_INIT以合适的方式返回传递的指针的地址,以用作列表的初始化程序:

struct list_head lst1;
/* .... */
INIT_LIST_HEAD(&lst1);



struct list_head lst2 = LIST_HEAD_INIT(lst2);
于 2012-04-21T19:26:44.913 回答