通常实现双向链表的数据结构:

struct list_node1{struct list_node1 *next,*prev;type1 m1;type2 m2;
};
struct list_node2{struct list_node2 *next,*prev;type1 m1;type2 m2;
};
……

对于每一种数据结构都定义了其特定的实现链表的结构和对应的方法(add/del)操作链表;

  但对于具有大量不同数据结构,都要使用链表的系统中,如果为每一种数据结构定义特定的结构,和操作方法,

无疑使代码变得重复和臃肿,需要实现一种通用的双向链表方法,对各种数据结构都能适用。

  C语言中又没有C++里面的模板,该如何实现呢?

linux内核中大量使用如下数据结构实现双向链表:

struct list_head {struct list_head *next, *prev;
};

  如果需要有某种数据结构的双向队列,就在这种结构内部放一个list_head数据结构成员。

struct kobject {const char        *name;struct list_head    entry;struct kobject        *parent;struct kset        *kset;
}

形成了如下结构:

    

如何通过kobject 链表结构中的 list_head 成员entry访问下一个成员呢?

系统提供了宏list_entry:

#define list_entry(ptr, type, member) \ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
//访问链表成员
kobject *obj  = objList;
kobject *nextObj = (kobject *)list_entry(obj->entry->next,struct kobject,entry);

这个list_entry是什么道理呢:

  ptr:是指向当前kobject结构对象中的数据成员entry,(char *)(ptr):entry成员地址 ——AddrA

  (unsigned long)(&((type *)0)->member)):将地址0转化为类型为type(struct kobject )对象,取member(entry)成员的地址——AddrB

  (type *)(AddrA - AddrB):得到kobject结构对象的首地址,转化为kobject对象。

  这里需要关注的就是AddrB:将地址0转化为类型为type(struct kobject )对象,取member(entry)成员的地址。

    表示当struct kobject 对象首地址为0时,得到成员member(entry)的地址,相对首地址的偏移地址。

    通过struct kobject 对象中member(entry)的地址 ,以及相对首地址的偏移量,就能计算出struct kobject 对象的首地址。

如下结构:

    

  充分利用了C语言中直接操作内存地址的特性。

Linux利用list_head结构实现双向链表相关推荐

  1. linux内核重要结构体,Linux中list_head结构体相关 | 技术部落

    在Linux内核中,提供了一个用来创建双向循环链表的结构 list_head.虽然linux内核是用C语言写的,但是list_head的引入,使得内核数据结构也可以拥有面向对象的特性,通过使用操作li ...

  2. [转]深入理解linux内核list_head

    http://blog.chinaunix.net/uid-27122224-id-3277511.html 深入理解linux内核list_head的实现 2012-07-17 17:37:01 分 ...

  3. linux文件夹前的描述,Linux对内存结构的描述

    Linux对内存结构的描述 1.查看Linux程序运行时状态 Linux在运行可执行文件时,该状态信息全部在/porc/${PID}中. proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外 ...

  4. (第五篇)Linux操作系统基本结构介绍

    Linux操作系统基本结构介绍 Linux系统一般有4个主要部分:内核.shell.文件系统和应用程序.内核.shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序.管理文件并使用 ...

  5. linux利用patch和diff命令制作文件补丁

    linux利用patch和diff命令制作文件补丁 因为在 u-boot 移植过程中,有几处通用文件要修改,如果每次都要手动修改就太麻烦了.制作补丁可以解决这个问题. 学习资料的收集比较简单,方法一类 ...

  6. Linux 变量和结构体

    Linux 变量和结构体 /* 设备号 主设备号 次设备号 */ dev_t dev #define MAJOR(dev) ((unsigned int) ((dev) >> MINORB ...

  7. Linux内核list_head学习(二)

    前一篇文章讨论了list_head 结构的基本结构和实现原理,本文主要介绍一下实例代码. 自己如果想在应用程序中使用list_head 的相应操作(当然应该没人使用了,C++ STL提供了list 用 ...

  8. Linux内核--链表结构

    一.前言     Linux内核链表结构是一种双向循环链表结构,与传统的链表结构不同,Linux内核链表结构仅包含前驱和后继指针,不包含数据域.使用链表结构,仅需在结构体成员中包含list_head* ...

  9. 大数据技术之_01_Linux学习_01_linux的入门+VM和linux的安装+linux的目录结构+远程登录到linux服务器+vi和vim编辑器+开机、重启和用户登录注销+用户管理+用户组管理

    大数据学习之_01_Linux学习_01 1 linux的入门 1.1 Linux的介绍 2 VM和linux的安装 2.1 安装vm和Centos 2.1.1 基本说明 2.1.2 CentOS安装 ...

最新文章

  1. 17岁少年买不到回国机票就攻击航司系统,获刑四年!自称因疫情严重和女朋友怀孕压力大...
  2. MS CRM 2011 Quick Find Active View
  3. 用Socket 打造跨语言跨操作系统的网络MORPG游戏(二)
  4. ITK:计算梯度各向异性扩散
  5. vim 底行命令模式的正则表达式(匹配模式)
  6. 数据绑定 单个对象和集合绑定差异
  7. mysql如何创建用户代码_MySQl创建用户和授权的方法介绍(代码示例)
  8. bzoj1597 [Usaco2008 Mar]土地购买
  9. UVA10735 Euler Circuit题解
  10. python中正则表达式的用法_详解Python中的正则表达式的用法
  11. 服务器的hosts文件位置,Hosts文件位置和书写规范
  12. win下文件共享多种方式
  13. ArcGIS软件操作问题及解决方法总结
  14. Mac安装双系统的那些坑
  15. OpenGL核心技术之法线贴图
  16. 老徐小程序之小程序怎么选?
  17. python实现商品管理系统_商品管理系统(示例代码)
  18. 获取电脑ip并输入微信发送
  19. ninjia必须以root权限运行问题
  20. vmware之设置共享文件夹

热门文章

  1. C++提高部分_C++类模板中成员函数的创建时机---C++语言工作笔记089
  2. Docker应用容器引擎_简介---Docker工作笔记003
  3. MyCat分布式数据库集群架构工作笔记0016---高可用_单表存储千万级_海量存储_垂直分库划分原则
  4. 图像增强(一):randaugment
  5. vc 2010 下打包dll 的问题
  6. 关于vc++调用 exe文件的问题
  7. python编程(你的电脑能够执行多少线程和进程)
  8. 用汇编的眼光看C++(之退出流程)
  9. c语言cin cou头文件,c+第五次实验
  10. java创建线程池几种方式_Java 创建线程池两种不同方法的比较