发布时间:2026/8/24 14:51:29
从零开始的敲代码生活--数据结构篇(内核链表) 一、内核链表基础概念普通链表数据域里面包含指针。 内核链表不把数据放在链表结点内部链表结点只存两个指针prev/next嵌入到自定义结构体中称为“侵入式链表”。 本质是双向循环链表有一个哨兵头结点不存有效数据哨兵的prev指向链表尾next指向链表第一个有效结点。优点通用一套链表代码可以管理任意自定义数据结构体双向循环头尾操作O(1)内核广泛使用不需要管理计数clen通过container_of宏由链表指针反推得到外部结构体首地址。缺点理解门槛高必须掌握container_of没有自带结点计数如需数量需要自己遍历统计。文件说明klisth.h内核链表头文件模拟linux内核list_headklist.c简单封装对外接口main_klist.c测试main函数注意Linux内核源码的list_head是纯头文件宏/内联函数没有.c文件这里为贴合文章格式做简单封装。二、头文件 klisth.h#ifndef _KLIST_H #define _KLIST_H #include stdio.h #include stdlib.h //内核链表结点只有两个指针无数据 typedef struct list_head { struct list_head *prev; struct list_head *next; }list_head; //container_of宏根据成员地址反推整个结构体首地址 #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (unsigned long)(((type *)0)-member))) //初始化哨兵头结点 #define LIST_HEAD_INIT(name) { (name), (name) } #define LIST_HEAD(name) list_head name LIST_HEAD_INIT(name) //自定义数据结构体把list_head嵌入自己的结构体 typedef struct { int id; char name[20]; list_head node; //内核链表结点嵌入在这里 }Student_t; //函数声明 extern void list_init(list_head *head); extern void list_add_head(list_head *head, list_head *new); extern void list_add_tail(list_head *head, list_head *new); extern void list_del(list_head *pos); extern int list_is_empty(list_head *head); //遍历宏 #define list_for_each(pos, head) \ for(pos (head)-next; pos ! (head); pos pos-next) //遍历并拿到外部结构体指针 #define list_for_each_entry(stu, pos, head, member) \ for(pos (head)-next, stu container_of(pos, Student_t, member);\ pos ! (head);\ pos pos-next, stu container_of(pos, Student_t, member)) #endif三、功能实现 klist.c模拟内核链表基础操作内核中原为static inline这里封装成函数方便阅读。1. list_init 初始化哨兵头结点功能哨兵结点自环prev、next指向自己。#include klisth.h void list_init(list_head *head) { head-next head; head-prev head; }2. list_add_head 头插哨兵之后插入void list_add_head(list_head *head, list_head *new) { new-next head-next; new-prev head; head-next-prev new; head-next new; }3. list_add_tail 尾插哨兵的prev前面插入void list_add_tail(list_head *head, list_head *new) { new-next head; new-prev head-prev; head-prev-next new; head-prev new; }4. list_del 删除指定结点只摘链不free内存重要list_del只是把结点从链表摘出去不会释放结点对应的内存free由用户自己完成。void list_del(list_head *pos) { pos-prev-next pos-next; pos-next-prev pos-prev; pos-next NULL; pos-prev NULL; }5. list_is_empty 判断链表是否为空int list_is_empty(list_head *head) { return head-next head; }四、测试main函数 main_klist.c#include klisth.h int main(void) { //1.定义哨兵头结点 LIST_HEAD(stu_head); //申请3个学生结构体 Student_t *s1 malloc(sizeof(Student_t)); Student_t *s2 malloc(sizeof(Student_t)); Student_t *s3 malloc(sizeof(Student_t)); if(s1NULL||s2NULL||s3NULL) { printf(malloc error\n); return -1; } s1-id 1001; snprintf(s1-name,sizeof(s1-name),zhangsan); s2-id 1002; snprintf(s2-name,sizeof(s2-name),lisi); s3-id 1003; snprintf(s3-name,sizeof(s3-name),wangwu); //尾插把结构体内部的node挂入链表 list_add_tail(stu_head, s1-node); list_add_tail(stu_head, s2-node); list_add_tail(stu_head, s3-node); printf(遍历学生链表:\n); list_head *pos; Student_t *pstu; list_for_each_entry(pstu, pos, stu_head, node) { printf(id:%d name:%s\n, pstu-id, pstu-name); } //删除s2结点 list_del(s2-node); free(s2); s2 NULL; printf(删除lisi之后:\n); list_for_each_entry(pstu, pos, stu_head, node) { printf(id:%d name:%s\n, pstu-id, pstu-name); } //全部释放 while(!list_is_empty(stu_head)) { pos stu_head.next; list_del(pos); pstu container_of(pos, Student_t, node); free(pstu); } return 0; }五、编译运行内存检测编译gcc main_klist.c klist.c -o klist_demo运行程序./klist_demovalgrind检测内存泄漏valgrind --leak-checkfull ./klist_demo注意list_del()只做摘链不会free内存必须手动free外层结构体container_of是内核链表灵魂由链表成员指针找回整个结构体哨兵结点LIST_HEAD本身不存业务数据内核链表没有维护clen计数求长度需要遍历计数。

相关新闻

2026/8/24 14:51:29

OpenAI Codex Harness 深度解析

从大模型竞争,到 Agent 基础设施竞争。过去几年,AI 竞争的核心一直围绕: 参数规模Benchmark 分数推理能力上下文长度 但是进入 Agent 时代以后,一个新的关键词正在出现:Harness(智能体运行框架)…

2026/8/24 14:51:29

Graphiti:面向 AI Agent 的时序知识图谱框架详解-王仕宇

从 Ontology、Knowledge Graph 到 GraphRAG,让 AI Agent 拥有真正的长期记忆能力。 项目地址: https://github.com/getzep/graphiti 一、为什么需要 Graphiti? 过去一年,RAG(Retrieval-Augmented Generation&#xf…

2026/8/24 16:51:49

多目标规划:从帕累托最优到NSGA-II的数学建模实战

1. 项目概述:从单目标到多目标的思维跃迁在数学建模的实战中,我们常常会遇到一个核心矛盾:现实世界的问题很少是“非黑即白”的单目标决策。比如,一个城市在规划新工业园区时,既要追求经济效益最大化(产值最…

2026/8/24 0:07:22

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/24 1:12:32

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/24 8:17:29

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/24 1:09:25

3条命令跑通LocalAI:无GPU本地AI引擎部署

3条命令跑通LocalAI:无GPU本地AI引擎部署 【免费下载链接】LocalAI LocalAI is the open-source AI engine. Run any model - LLMs, vision, voice, image, video - on any hardware. No GPU required. 项目地址: https://gitcode.com/GitHub_Trending/lo/LocalAI…

2026/8/24 1:09:25

AI推理性能测试怎么做:MLPerf Inference完整上手指南

AI推理性能测试怎么做:MLPerf Inference完整上手指南 【免费下载链接】inference Reference implementations of MLPerf inference benchmarks 项目地址: https://gitcode.com/gh_mirrors/inf/inference 同一个模型换一张卡,速度快多少你知道吗&a…

2026/8/24 13:42:17

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/23 6:14:43

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/23 4:22:01

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…