C语言struct list_head大小计算及使用方法相关问题咨询
结构体与链表相关问题解答
1 struct list_head的作用、成员含义与大小计算
- 作用:这是通用双向链表的标准实现构件,最经典的应用是Linux内核的双向链表机制,核心作用是解耦链表逻辑和业务数据结构,不需要在每个需要链表功能的自定义结构体里重复编写前后指针代码,只需要将
struct list_head作为成员嵌入自定义结构体即可。 next/prev成员含义:两个成员都是指向struct list_head类型实例的指针,分别存储链表中当前节点的后一个节点、前一个节点中list_head成员的内存地址,以此串起整个链表的所有节点。- 大小计算逻辑:C语言结构体的大小为所有成员的内存占用总和加上对齐填充开销,该结构体仅包含两个指针类型成员,编译期即可确定每个指针的大小,因此不需要额外的基础算术类型成员也能计算总大小。
2 测试代码输出结果解释
你给出的测试输出8 16 16成因如下:
sizeof(p)结果为8:p是struct list_head*类型的指针变量,64位系统下所有类型的指针变量内存占用都固定为8字节,这个大小由CPU的寻址位宽决定:64位CPU的虚拟地址长度为64位,刚好需要8字节存储,因此所有指针的sizeof结果都是8。sizeof(*p)结果为16:*p是对指针p解引用,得到的是struct list_head类型的实例,该类型包含两个8字节的指针成员,且成员对齐无额外填充开销,因此总大小为8*2=16。sizeof(v)结果为16:v是struct list_head类型的变量,和*p属于同一类型,因此大小同样为16。- 关于无显式基础类型也能计算大小的疑问:指针本身就是C语言的原生基础类型,并非只有int、char这类算术类型才算基础类型。只要结构体的所有成员大小在编译期可确定,编译器就能计算出整个结构体的大小,不需要包含算术类型成员。
3 struct list_head的使用方法
使用逻辑是将其嵌入到你自己的业务结构体中,示例如下:
// 自定义业务结构体,嵌入list_head成员 struct book { char title[50]; float price; struct list_head node; // 链表节点成员,用来串起所有book实例 };
赋值与使用规则:
- 链表初始化时,头节点的
next和prev都指向自身,代表空链表。 - 添加节点时,将新节点中
node成员的next和prev指向相邻节点的node成员地址即可,比如已有头节点struct list_head book_list,新增book实例new_book,就可以通过操作new_book.node的前后指针完成插入。 - 遍历链表时,可以通过标准的
container_of宏,通过node成员的地址反查整个book结构体的首地址,即可获取对应的业务数据。
内容的提问来源于stack exchange,提问作者user786
相关产品推荐
相关产品推荐

