从零开始的敲代码生活--数据结构篇(内核链表)
一、内核链表基础概念普通链表数据域里面包含指针。 内核链表不把数据放在链表结点内部链表结点只存两个指针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计数求长度需要遍历计数。

相关新闻

OpenAI Codex Harness 深度解析

OpenAI Codex Harness 深度解析

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

2026/8/24 14:51:25 阅读更多 →
Graphiti:面向 AI Agent 的时序知识图谱框架详解-王仕宇

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

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

2026/8/24 14:51:25 阅读更多 →
RAG 实战教程(三):PDF、Word、Markdown 多文档知识库实战——文档解析、清洗与智能索引

RAG 实战教程(三):PDF、Word、Markdown 多文档知识库实战——文档解析、清洗与智能索引

RAG 系列第三篇。 本篇将在第二篇「Python Qdrant 搭建第一个 RAG 知识库」的基础上继续升级,实现一个更加接近真实企业场景的知识库系统。 我们将支持: PDF 文档Word 文档Markdown 文档HTML 网页文档清洗Metadata 管理增量索引多格式统一入库 最终实现…

2026/8/24 14:51:25 阅读更多 →

最新新闻

AdGuard Home 部署与配置优化完整指南:3 个关键点让家庭网络去广告、解析更快

AdGuard Home 部署与配置优化完整指南:3 个关键点让家庭网络去广告、解析更快

AdGuard Home 部署与配置优化完整指南:3 个关键点让家庭网络去广告、解析更快 【免费下载链接】AdGuardHome Network-wide ads & trackers blocking DNS server 项目地址: https://gitcode.com/gh_mirrors/ad/AdGuardHome 这是一份面向新手的 AdGuard Ho…

2026/8/24 16:30:00 阅读更多 →
数学模型实战指南:从原理到应用,构建与部署全流程解析

数学模型实战指南:从原理到应用,构建与部署全流程解析

1. 从“黑箱”到“利器”:数学模型到底是什么?干了这么多年数据分析和技术咨询,我经常被问到的一个问题是:“你们搞的那个数学模型,到底是个啥?是不是就是一堆看不懂的公式?” 这让我意识到&…

2026/8/24 16:30:00 阅读更多 →
模糊老视频如何快速放大变高清:ComfyUI-SeedVR2 视频放大完整实操指南

模糊老视频如何快速放大变高清:ComfyUI-SeedVR2 视频放大完整实操指南

模糊老视频如何快速放大变高清:ComfyUI-SeedVR2 视频放大完整实操指南 【免费下载链接】ComfyUI-SeedVR2_VideoUpscaler Official SeedVR2 Video Upscaler for ComfyUI 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-SeedVR2_VideoUpscaler ComfyUI-…

2026/8/24 16:30:00 阅读更多 →
数值分析插值法核心思想:从拉格朗日到牛顿插值的算法选择与误差控制

数值分析插值法核心思想:从拉格朗日到牛顿插值的算法选择与误差控制

1. 项目概述与核心价值最近在整理资料时,翻出了当年学习钟尔杰老师《数值分析》课程时,自己啃下来的第二章思考题解答。这门课是很多理工科,尤其是计算数学、计算机、物理、工程类专业的必修硬核课程,而钟尔杰老师的教材以其理论严…

2026/8/24 16:30:00 阅读更多 →
三步备份全部QQ空间历史说说:GetQzonehistory 完整使用指南

三步备份全部QQ空间历史说说:GetQzonehistory 完整使用指南

三步备份全部QQ空间历史说说:GetQzonehistory 完整使用指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 想翻五年前发的那条动态,QQ 空间页面却怎么都滑不到最…

2026/8/24 16:30:00 阅读更多 →
HyperDown 快速上手:1849 行单文件的 PHP Markdown 解析器

HyperDown 快速上手:1849 行单文件的 PHP Markdown 解析器

HyperDown 快速上手:1849 行单文件的 PHP Markdown 解析器 【免费下载链接】HyperDown 一个结构清晰的,易于维护的,现代的PHP Markdown解析器 项目地址: https://gitcode.com/gh_mirrors/hy/HyperDown 如果你正在用 PHP 写博客或内容后…

2026/8/24 16:28:52 阅读更多 →

日新闻

前端内容安全与依赖审计实践

前端内容安全与依赖审计实践

前端内容安全与依赖审计实践 前端安全依赖分层防护。没有任何单一配置能替代输出编码、权限校验和依赖更新。 把不可信内容当作数据 默认使用框架的转义能力;确需渲染 HTML 时,先在服务端或可信的客户端库中进行白名单过滤。避免把用户输入直接赋给 inne…

2026/8/24 1:08:15 阅读更多 →
Windows登录密码存储机制全解析:从哈希算法到安全加固实战

Windows登录密码存储机制全解析:从哈希算法到安全加固实战

1. 项目概述:Windows登录密码的“黑匣子”每次你按下CtrlAltDel,输入密码,然后看到那个熟悉的桌面,这背后发生了一系列复杂而精密的操作。作为一名长期与Windows系统打交道的从业者,我经常被问到:“我的密码…

2026/8/24 1:08:15 阅读更多 →
AI面试系统安全挑战与解决方案

AI面试系统安全挑战与解决方案

1. 项目概述:AI面试系统的安全挑战去年参与某跨国企业AI面试系统部署时,遇到一个典型案例:候选人在视频面试中无意提到竞争对手产品名称,系统竟自动将该信息关联到企业知识库并生成竞品分析报告。这个看似"智能"的功能&…

2026/8/24 1:08:15 阅读更多 →

周新闻

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

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

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

2026/8/24 0:06:02 阅读更多 →
SIP通话转接原理与REFER方法实战解析

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

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

2026/8/24 0:20:20 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

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

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

2026/8/24 0:14:11 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/23 18:47:06 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/23 12:10:44 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/24 11:20:22 阅读更多 →