链表是Linux系统中常见的一种数据结构,在内核中经常使用,在用户态也需要使用,但我们并不需要重新写一个新的链表模型,可以直接引用内核的数据定义。
先来看这个链表的定义(来自内核文件定义)。
struct list_head {
struct list_head *next, *prev;
};
定义了一个结构,成员为指向结构的指针。我们在引用时如何在链表中插入数据?很简单,可以定义一个自己的结构。例如:
struct mystruct {
int number;
char item[20];
struct list_head list;
};
然后对这个插入的链表进行初始化(来自内核文件定义)
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
可以看到这个初始化就是将链表成员指向自身。
链表创建完成后就可以开始使用了,首先是插入成员。使用这个定义
static inline void list_add_tail(struct list_head *new, struct list_head *head),
@new是新加入的节点,@head是要插入的链表首地址。
功能是将new节点插入到节点head前。
列出所有节点成员
首先检查链表是否为空,再进行查找
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
先遍历一次链表
#define list_for_each(pos, head) \
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
pos = pos->next)
然后查找每个节点
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
container_of确实很精妙,从list找到节点的指针,使用相对偏移地址。
删除所有节点
所有节点的添加都是malloc申请的,使用完后要释放。删除整个列表,首先遍历一次整个链表,然后使用list_del删除节点
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
释放节点资源
使用list_entry取得节点地址,调用free进行释放。
全部节点释放完后,再调用free(head)将表释放掉,这样所有的链表就释放完成了。
参考连接:
http://blog.chinaunix.net/uid-27033491-id-3296804.html
/usr//include/linux/list.h
阅读(449) | 评论(0) | 转发(0) |