侵入式链表什么意思?
一、侵入式链表
侵入式链表让结构体包含一个成员变量,该成员变量是一个通用的链表结点。普通的单链表的结点链接域存的是下一个结点的内存首地址,而侵入式单链表的结点链接域存的是下一个结点的链接域成员变量的内存首地址。
typedef struct list_s {
struct list_s *next;
} list_t;
typedef struct foo_s {
int data;
list_t link;
} foo_t;
下面给出一个最简单的侵入式单链表实现。
1. list.h
1 #ifndef _LIST_H
2 #define _LIST_H
3
4 #ifdef __cplusplus
5 extern “C” {
6 #endif
7
8 /**
9 * offsetof – offset of a structure member
10 * @TYPE: the type of the struct.
11 * @MEMBER: the name of the member within the struct.
12 */
13 #define offsetof(TYPE, MEMBER) ((size_t)(&(((TYPE *)0)->MEMBER)))
14
15 /**
16 * container_of – cast a member of a structure out to the containing structure
17 * @ptr: the pointer to the member.
18 * @type: the type of the container struct this is embedded in.
19 * @member: the name of the member within the struct.
20 *
21 */
22 #define container_of(ptr, type, member) ({ \
23 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
24 (type *)( (char *)__mptr – offsetof(type, member) );})
25
26 typedef struct list_s {
27 struct list_s *next;
28 } list_t;
29
30 typedef void (*list_handler_t)(void *arg);
31
32 extern void list_init(list_t **head, list_t *node);
33 extern void list_fini(list_t *head, list_handler_t fini);
34 extern void list_show(list_t *head, list_handler_t show);
35
36 #ifdef __cplusplus
37 }
38 #endif
39
40 #endif /* _LIST_H */
2. list.c
1 /*
2 * Generic single linked list implementation
3 */
4 #include
5 #include “list.h”
6
7 void
8 list_init(list_t **head, list_t *node)
9 {
10 static list_t *tail = NULL;
11
12 if (*head == NULL) {
13 *head = tail = node;
14 return;
15 }
16
17 tail->next = node;
18 tail = node;
19 node->next = NULL;
20 }
21
22 void
23 list_show(list_t *head, list_handler_t show)
24 {
25 for (list_t *p = head; p != NULL; p = p->next)
26 show(p);
27 }
28
29 void
30 list_fini(list_t *head, list_handler_t fini)
31 {
32 list_t *p = head;
33 while (p != NULL) {
34 list_t *q = p;
35 p = p->next;
36 fini(q);
37 }
38 }
延伸阅读:
二、侵入式的好处
一般来说,大家都会优先选择使用非侵入式的实现。因为侵入式实现需要将一些逻辑耦合到业务代码中,因此为人所不喜。但是在背景介绍中提到的场景下,侵入式实现有显著的好处,从而使得侵入式实现被广泛的使用。我们在此不再强调侵入式与非侵入式的区别,主要考虑一下侵入式链表的优势有哪些。
更好的 Data Locality
std::list
更友好的 API
对于侵入式链表,我们拿到数据就可以将这个节点从链表中摘除,而无需再去定位其 iterator,然后再去找到对应的容器 erase 这个 iterator。
脱离容器进行生命周期管理
最主要的应用场景是同一份对象需要在多个容器中共享,例如在背景介绍中提到的实现 LRU 的场景,又例如需要将同一份数据加入多个链表中。因此侵入式链表需要用户自己管理数据节点生命周期的特性在这里就成为了一个优点。
相关推荐HOT
更多>>mysql的MEMORY引擎为什么没有redis的应用广泛?
一、mysql的MEMORY引擎为什么没有redis的应用广泛从kv缓存的作用看,mysql优点不在kv缓存上,用它做kv缓存维护成本高,redis安装启动使用简单,...详情>>
2023-10-20 18:38:17什么是PWA?
一、什么是PWAPWA是渐进式 Web 应用,运用现代的 Web API 以及传统的渐进式增强策略来创建跨平台 Web 应用程序。。这些应用无处不在、功能丰富...详情>>
2023-10-20 14:02:19软件包“被标记为手动安装”是什么意思?
一、软件包“被标记为手动安装”是什么意思当你尝试安装已安装的库或开发包时,你会看到此消息。意味着该软件包是由用户手动安装的,而不是通过...详情>>
2023-10-20 11:47:20什么是Flash?
一、什么是FlashFlash是一种基于向量图形的动画技术,由Adobe公司开发。它支持多媒体、游戏、网站设计等应用,可以在各种平台和设备上实现高质...详情>>
2023-10-20 10:24:01热门推荐
一个优异的web前端,需要具备哪些条件?
沸华为自研的数据库gaussdb有哪些优势?
热数据库ER图是怎么做的?
热为什么使用MySQL?
新什么是synchronized?
既然MySQL中InnoDB使用MVCC,为什么REPEATABLE-READ不能消除幻读?
分布式系统里用户ID生成有什么好的方法和规则能满足“少数、尽量短、不能直接看出规则”这几个条件?
isKindOfClass、isMemberOfClass 作用分别是什么?
APP开发流程步骤有哪些?
mysql的MEMORY引擎为什么没有redis的应用广泛?
webpack proxy工作原理为什么能解决跨域?
python的五个特点?
staticmethod和classmethod的区别?
Android App设计开发应遵循哪些原则?