ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

(转载)计算结构体首地址的技巧

2021-07-25 11:01:46  阅读:148  来源: 互联网

标签:struct 体首 member 地址 结构 转载 type name


struct ABC
{
int a;
int b;
int c;
};

+----------+ <------我们需要计算的是这个地址。
| a(4Byte) |
+----------+ <------这个地址是已知的。
| b(4Byte) |
+----------+
| c(4Byte) |
+----------+
通过上图可看出,只需要把当前知道的成员变量的地址ptr,减去它在结构体当中相对偏移量(4),就得到了结构体的首地址(ptr-4).
设计一个type类型的结构体,起始地址为0,编译器将结构体的起始的地址加上此结构体成员变量的偏移得到此结构体成员变量的偏移地址,由于设计的结构体起始地址为0,所以此结构体成员变量的偏移地址就等于其成员变量在结构体内的距离结构体开始部分的偏移量。

Linux内核中,用两个非常巧妙地宏实现了,一个是offsetof宏,另一个是container_of宏:
1.offsetof宏(获得一个结构体变量成员在此结构体中的偏移量)
#define offsetof(struct_type, member_name) ((size_t) & ((struct_type *)0)->member_name )
【分析】:
(1) 该宏中,struct_type为结构体类型,member_name为结构体内的变量名
(2) ((struct_type *)0) 是欺骗编译器说有一个指向结构struct_type 的指针,其地址值0
(3) &((struct_type *)0)->member_name 是要取得结构体struct_type中成员变量member_name的地址.
(4) 最后将其值强转为size_t,即转化为一个常数值,而不是将其当作地址进行使用。
因为基址为0,所以,这时member_name的地址当然就是member_name在struct_type中的偏移了。

2. container_of宏(从结构体[struct_type]某成员变量[member_name]指针[member_addr]来求出该结构体[struct_type]的首指针)
#define container_of(member_addr, struct_type, member_name) ({const typeof( ((struct_type *)0)->member_name ) *__mptr = (member_addr); (struct_type *)( (char *)__mptr - offsetof(struct_type,member_name) );})或者直接定义#define container_of(member_addr, struct_type, member_name)   ((struct_type *)( (char *)member_addr - offsetof(struct_type,member_name) ))
【分析】:
(1)typeof( ( (struct_type *)0)->member )为取出member_name成员的变量类型。
(2) 定义__mptr指针member_addr为指向该成员变量的指针(即指向member_addr所指向的变量处)
(3) (char *)__mptr - offsetof(struct_type,member_name)) 用该成员变量的实际地址减去该变量在结构体中的偏移,来求出结构体起始地址。
(4) ({ })这个扩展返回程序块中最后一个表达式的值。

 

转载于:https://www.cnblogs.com/eric-geoffrey/p/3811630.html

标签:struct,体首,member,地址,结构,转载,type,name
来源: https://www.cnblogs.com/mickey-double/p/15057247.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有