list
API不會動態分配任何內存。我自己發現這件事有點令人費解。這裏的問題在於,Linux是用C編寫的,而不是C++,但是它以一種完全面向對象的方式實現了事物,但是在C中它看起來像是從頭到尾。它的工作原理如下(這也適用於其他幾個Linux API,例如kobj
):
您定義了一些struct
,它應該是列表的成員。與通常想象鏈接列表的方式相反,通過分配一些不透明的列表項並將指針指向實際對象,該對象將不會被放入列表中,您使成爲您的struct
的實際成員 :
struct something {
struct list_head list;
uint8_t some_datum;
uint16_t some_other_datum;
void *a_pointer;
};
你的列表會出現一些獨立struct list_head
:
static LIST_HEAD(list_of_somethings);
將元素添加到list_of_somethings
你現在會做類似
struct something *s = kmalloc(sizeof(*s), GFP_KERNEL);
s->some_datum = 23;
s->some_other_datum = 0xdeadbeef;
s->a_pointer = current;
list_add(&s->list, &list_of_somethings);
換句話說,你已經分配了元素。這看起來完全不可思議,但像f * ck一樣優雅。這種「設計模式」允許在C中有不透明類型的列表,這在以另一種方式做起來並不容易:列表本身就是一堆指向對方的列表。正如你知道實際的struct
你expeting作爲一個程序員,你知道這個struct
的元素是實際list_head
並且可以使用container_of
宏得到的指針,你把名單最終struct
:
struct list_head *p = &list_of_somethings.next;
struct something *s = container_of(p, struct something, list);
pr_notice("some data = %i\n", s->some_data);
注意,表示該清單自身的實際struct list_head
由<linux/list.h>
定義的迭代宏特殊處理,即
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
的list_of_somethings
地址將被用於阻止我是否迭代到達列表的末尾(或者實際上是列表對象)。 這也是爲什麼空列表被定義爲具有next
和prev
指向struct list_head
本身的原因。
我也需要一些時間來包裹我的頭。 ;)
你也可以參考這個答案:http://stackoverflow.com/questions/33850930/correct-way-to-join-two-double-linked-list/ – 0andriy