20.driverbase-CONTAINING_RECODE和双向链表
CONTAINING_RECODE
#define CONTAINING_RECORD(address, type, field) ((type *)( \(PCHAR)(address) - \(ULONG_PTR)(&((type *)0)->field)))
addr: 结构体中某个成员变量的地址
type: 结构体的原型
field: 结构体的某个成员(与前面相同)
根据结构体中的某成员的地址来推算出该结构体整体的地址,这是个万能公式,如下例:
typedef struct _MYDATASTRUCT
{ULONG number;LIST_ENTRY ListEntry;
} MYDATASTRUCT, *PMYDATASTRUCT;
PLIST_ENTRY pEntry = RemoveTailList(&linkListHead);
PMYDATASTRUCT pData = CONTAINING_RECORD(pEntry,MYDATASTRUCT,ListEntry);
含义如下:pEntry代表MYDATASTRUCT的变量中的ListEntry的地址,pData为MYDATASTRUCT的变量地址
双向链表
typedef struct _LIST_ENTRY {struct _LIST_ENTRY *Flink;struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
1.首先初始化链表,即Flink和Blink指向自身
VOID FORCEINLINE InitializeListHead(IN PLIST_ENTRY ListHead)
{ListHead->Flink = ListHead->Blink = ListHead;
}
#define IsListEmpty(ListHead) \((ListHead)->Flink == (ListHead))
VOID
FORCEINLINE
InsertHeadList(IN PLIST_ENTRY ListHead,IN PLIST_ENTRY Entry)
{PLIST_ENTRY Flink;Flink = ListHead->Flink;Entry->Flink = Flink;Entry->Blink = ListHead;Flink->Blink = Entry;ListHead->Flink = Entry;// 插入到ListHead以后
}
VOID
FORCEINLINE
InsertTailList(IN PLIST_ENTRY ListHead,IN PLIST_ENTRY Entry)
{PLIST_ENTRY Blink;Blink = ListHead->Blink;// 取得原始尾部Entry->Flink = ListHead;// 新的尾部的后一元素是头(环)Entry->Blink = Blink; // 新的尾部前一元素是原始尾部Blink->Flink = Entry; // 原始尾部的后一元素是新的尾部ListHead->Blink = Entry;// 头的前一元素是新的尾部(环)
}
后向插入Entry3
VOID LinkListTest()
{LIST_ENTRY linkListHead;//初始化链表InitializeListHead(&linkListHead);PMYDATASTRUCT pData;ULONG i = 0;//在链表中插入10个元素KdPrint(("Begin insert to link list"));for (i=0 ; i<10 ; i++){pData = (PMYDATASTRUCT)ExAllocatePool(PagedPool,sizeof(MYDATASTRUCT));pData->number = i;InsertHeadList(&linkListHead,&pData->ListEntry);}//从链表中取出,并显示KdPrint(("Begin remove from link list\n"));while(!IsListEmpty(&linkListHead)){PLIST_ENTRY pEntry = RemoveTailList(&linkListHead);pData = CONTAINING_RECORD(pEntry,MYDATASTRUCT,ListEntry);KdPrint(("%d\n",pData->number));ExFreePool(pData);}
}
20.driverbase-CONTAINING_RECODE和双向链表相关推荐
- C++知识点 —— 整合(持续更新中)
本文记录自己在自学C++过程中不同于C的一些知识点,适合于有C语言基础的同学阅读.如果纰漏,欢迎回复指正 目录 第一部分 基础知识 一.HelloWorld与命名空间 二.引用和引用参数 2.1引用的 ...
- C++知识点 —— 整合
本文记录自己在自学C++过程中不同于C的一些知识点,适合于有C语言基础的同学阅读.如果纰漏,欢迎回复指正 目录 第一部分 基础知识 一.HelloWorld与命名空间 二.引用和引用参数 2.1引用的 ...
- 利用php屏蔽海外ip访问,高效实现
<?php/*** 屏蔽海外ip访问* 使用ip2long函数得到ip转为整数的值,判断值是否在任一一个区间中* 以下是所有国内ip段* 调用方法:IschinaIp($ALLIPS)* 返回值 ...
- C++/C++11中std::list双向链表的使用
std::list是双向链表,是一个允许在序列中任何一处位置以常量耗时插入或删除元素且可以双向迭代的顺序容器.std::list中的每个元素保存了定位前一个元素及后一个元素的信息,允许在任何一处位置以 ...
- 20道常见初级Java面试题
1.面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: - 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注 ...
- c语言结点初始化,C语言双向链表简单实现及图示(初始化/插入节点/删除节点)...
-------------------------------------------- 双向链表 - - - - - - - - - - - - - - - - - - - - - - - - - ...
- 20天拿到美团快手小米搜狐跟谁学offer
最近看了看外面的机会,特此汇总下,希望对读者有帮助. 战况 贝壳:一轮技术面,自挂东南枝. 脉脉:两轮技术面,自挂东南枝. 跟谁学:三轮技术面 + 一轮 HR 面. 搜狐:三轮技术面 + 一轮 HR ...
- 双向链表(C++实现)
// /// 这里建立两个类,一个节点类和一个List类,与单链表不同的是双向链表的节点要多一 // 个前驱指针,相应的,双向链表函数实现要与单链表实现有所差异 typedef int DataTyp ...
- 将二叉搜索树转换为有序的双向链表
题目:给出一个二叉搜索树,要求将它转换为有序的双向链表,要求不能添加新的节点空间. 思路:有序的双向链表,二叉搜索树的中序遍历是有序的. 递归: public class TreeNodeDemo { ...
最新文章
- linux查看python pip 安装包列表和安装路径
- 【软考-软件设计师】汇编程序基本原理
- 华大 MCU 之五 SPI 从机 DMA 模式 配置(不能正常接收问题处理)
- 计算机基础知识总结论文,大学计算机基础总结论文
- 解决df -h卡死问题
- CentOS下使用Varnish为网站加速
- Navicat Premium11连接Oracle出现ORA-28547:connection to server failed
- 小宇飞刀与xieyunc
- Hibernate 注解方式
- python数据集_在Python中如何差分时间序列数据集
- Centos7安装SCIP with AMPL
- pgadmin3连接mysql_启动PostgreSQL服务器 并用pgAdmin连接操作
- 统计学中p值计算公式_统计学中的p值怎么算,具体步骤
- 二项分布,柏松分布和正态分布
- Mac 增加国内节假日安排
- php 二维数组变一维数组,php中怎么将二维数组转为一维数组
- unity Color和Hex转化
- 1050Ti 安装CUDA、cuDNN
- arcgis地图加载离线地图
- 掌商科技成绩斐然 不忘行业和社会责任
热门文章
- ipad服务器已停止响应怎么办,如果iPad无法打开或者显示屏幕停止响应怎么办?要注意哪些方面...
- java中acos是什么意思_Java acos()方法
- 关于获取客户端公网IP问题
- 简书一下居住证的办理过程
- 岁月划过生命线——大三上
- Failed to enable unit: Unit file docker.service does not exist
- 华为电脑linux指纹,华为朱臣才:MateBook指纹解锁仅需一触
- 2022年12月10日(星期六):骑行樱花谷
- 小猫统计画股票K线图
- 为啥固态硬盘越用越慢?还可以拯救一下