內核鏈表
阿新 • • 發佈:2018-05-25
malloc print con int %d char* sizeof [] put
1 引言
如果大家用c做應用(哈哈,估計基本不用),就會發現總要造輪子,本著服務大家,方便自己的原則,搞點小程序方便大家做開發。
這裏就潑個內核鏈表的實現給大家(程序如果有問題,希望大家及時指正)使用。
為啥要用內核鏈表?
主要還是為了方便,比如用c做個項目需要多次用到鏈表,註意這裏的意思是多個鏈表中的數據類型不同,format as:
struct StringList { char str[256]; struct UserList* pre; struct UserList* next; }; strcut IntList {int id; struct Intlist* pre; struct Intlist* next; };
需要實現兩個鏈表的邏輯,因為鏈表是“數據相關”(自創詞)的。
內核鏈表是數據無關的,基本原理是通過結構體的一個元素地址從而可以獲取結構體入口地址,這塊不清楚的老鐵自行查一下container_of這個宏,這裏不再啰嗦。
2 扣出內核中的鏈表實現
# define POISON_POINTER_DELTA 0 #define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA) #defineLIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA) //計算member在type中的位置 #define offsetof(type, member) (size_t)(&((type*)0)->member)
//根據member的地址獲取type的起始地址 #define container_of(ptr, type, member) ({ const typeof(((type *)0)->member)*__mptr = (ptr); (type *)((char *)__mptr - offsetof(type, member)); })#define list_entry(ptr, type, member) \ container_of(ptr, type, member) #define list_first_entry(ptr, type, member) \ list_entry((ptr)->next, type, member) #define list_for_each(pos, head) for (pos = (head)->next; pos != (head); pos = pos->next) //鏈表結構 struct list_head { struct list_head *prev; struct list_head *next; }; static inline void init_list_head(struct list_head *list) { list->prev = list; list->next = list; } static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) prev->next = new; new->prev = prev; new->next = next; next->prev = new; } //從頭部添加 static inline void list_add(struct list_head *new , struct list_head *head) { __list_add(new, head, head->next); } //從尾部添加 static inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } static inline void __list_del(struct list_head *prev, struct list_head *next) { prev->next = next; next->prev = prev; } static inline void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); entry->next = LIST_POISON1; entry->prev = LIST_POISON2; } static inline void list_move(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); list_add(list, head); } static inline void list_move_tail(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); list_add_tail(list, head); }
//An example
int main(int argc, const char* argv[])
{
//Init List Head
struct list_head* global_head = (struct list_head*)malloc(sizeof(struct list_head));
init_list_head(global_head);
//Insert an value from tail
struct Val {
struct list_head node;
int value; //Identify your data on list
};
struct Val* v = (struct Val*)malloc(sizeof(struct Val));
struct list_head* node = v->node;
list_add_tail(node, global_head);
//travel the list.
struct list_head* p;
list_for_each(pos, global_head)
{
v = list_entry(pos, struct Val, value);
printf("%d ", v->value);
}
fputs();
return 0;
}
內核鏈表