宏offsetof分析
1、前言
在C语言的结构体中,由于字节对齐的问题,所以成员的地址并不能直接根据数据类型的大小进行计算,使用宏offsetof可以获得结构体成员相对于结构体首地址的字节偏移量。
2、offsetof宏实现
在C标准库中offsetof的声明如下,需要包含头文件<stddef.h>:
size_t offsetof(type, member);
参数:
type:结构体类型
member:结构体中成员的名称
返回值:
返回类型为size_t的值,表示type中member的偏移量
该宏在Linux内核源码内的实现如下:
#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
通过上面这个宏为什么能获取到结构体某个成员的偏移地址呢?首先,偏移地址的计算方法为:
当前的成员地址-结构体首地址=偏移地址
在offsetof宏中,将0地址强制转换成了(TYPE *)类型,也就是说结构体的首地址为0,所以根据偏移地址计算方法,可以知道当前成员的地址也就等于偏移地址,所以宏offsetof将成员的地址取出并返回,获得的就是某个成员的偏移地址了,返回值为size_t类型,需要引起一定的注意。
3、实例
下面是一个offsetof的使用实例,代码如下所示:
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h> struct s {
int i;
char c;
double d;
char a[];
}; int main(int argc, char *argv[])
{
printf("sizeof(struct s)=%zd\n", sizeof(struct s));
printf("offsets: i=%zd; c=%zd; d=%zd; a=%zd.\n",
offsetof(struct s, i), offsetof(struct s, c),
offsetof(struct s, d), offsetof(struct s, a)); exit(EXIT_SUCCESS);
}
使用gcc编译后运行结果如下所示:

由于字节对齐的原因,所以结构体s的大小为16个字节,假设结构体首地址从0开始,由于int类型占用4字节,所以地址0到3为变量i所用,char类型占用1字节,地址4为变量c所用,由于需要字节对齐并且double类型的开始地址必须是8的整数倍,因此地址5到7被填充,double类型占用8字节,地址8到15被变量d所用,a的地址则从地址16开始,因此,通过宏offsetof便可以得到结构体成员的偏移地址。
参考:
https://www.runoob.com/cprogramming/c-macro-offsetof.html
https://www.cnblogs.com/litifeng/p/7685378.html
宏offsetof分析的更多相关文章
- container_of宏定义分析---linux内核
问题:如何通过结构中的某个变量获取结构本身的指针??? 关于container_of宏定义在[include/linux/kernel.h]中:/*_** container_of - cast a ...
- 剖析linux内核中的宏-----------offsetof
offsetof用于计算TYPE结构体中MEMBER成员的偏移位置. #ifndef offsetof#define offsetof(TYPE, MEMBER) ((size_t) &((T ...
- linux内核container_of宏定义分析
看见一个哥们分析container_of很好,转来留给自己看 一.#define offsetof(TYPE, MEMBER) ((size_t) & ((TYPE *)0)->MEMB ...
- 《linux 内核全然剖析》 笔记 CODE_SPACE 宏定义分析
在memory.c里面.遇到一个宏定义,例如以下: #define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \ current->sta ...
- 宏_CRTIMP分析
CRTIMP是C run time implement的简写,C运行库的实现的意思. 作为用户代码,不应该使用这个东西. 该参数决定 运行时 到底用 动态链接库 还是静态链接 #ifndef _CRT ...
- C语言-宏定义与使用分析
1.C语言中的宏定义 #define是预处理器处理的单元实体之— #define定义的宏可以出现在程序的任意位置 #define定义之后的代码都可以使用这个宏 2.定义宏常量 #define定义的宏常 ...
- offsetof宏---个人笔记
标准库里面提供的offsetof(t,m)宏,用来计算两个变量在内存中的地址偏移量 #include <stdio.h>//原型: #define offsetof(TYPE, MEMBE ...
- 【宏蛋白组】iMetaLab平台分析肠道宏蛋白质组数据
目录 一.iMetaLab简介 二.内置工具与模块 1. Data Processing module 2. Functional Analysis 3. R Developing environme ...
- C语言笔记(结构体与offsetof、container_of之前的关系)
关于结构体学习,需要了解:结构体的定义和使用.内存对齐.结构体指针.得到结构体元素的偏移量(offsetof宏实现) 一.复习结构体的基本定义和使用 typedef struct mystruct { ...
随机推荐
- Linux 监控之 IO
简单介绍下 Linux 中与 IO 相关的内容. 简介 可以通过如下命令查看与 IO 相关的系统信息. # tune2fs -l /dev/sda7 ← 读取superblock信息 # blockd ...
- Python 绘图与可视化 matplotlib text 与transform
Text 为plots添加文本或者公式,反正就是添加文本了 参考链接:https://matplotlib.org/api/_as_gen/matplotlib.pyplot.text.html#ma ...
- python高级编程——线程和线程池
线程模块 线程的特点: 本质上是异步的.需要多个并发活动.每个活动的处理顺序可能是不确定的.或者说是随机的,不可预测的,宏观上是同时运行的 ...
- JS基石之-----数组转换为树结构函数
我们常常在做后台管理系统的时候 需要对数据进行组装成一个树装结构,这里特地将此方法进行封装: let data = [ { id: , text: }, { id: , text: }, { id: ...
- tcp / udp 协议及其实现的socket
一.tcp协议 1.1 基本知识 特点: 可靠,慢,全双工通信 建立连接时:三次握手 断开连接时:四次挥手 在建立起连接之后 发送的每一条信息都有回执 为了保证数据的完整性,还有重传机制 长连接:会一 ...
- Kubernetes概念之mater、node
很久没写博客了,终于把重心找回来了,不过没有以前有斗志.有理想.有目标了.慢慢来.你若问我我最近几年的规划是什么,还真不知道.突然发现摧毁一个人真的很简单.k8s也是一遍一遍的从入门到放弃,还是要好好 ...
- oracle查看表空间的真实使用情况
--查看表空间的真实使用情况 set linesize 500 pagesize 500 col tablespace_name format a25 col TP_REAL_GB format a1 ...
- 服务器学习--Linux基本操作指令
小编后续会持续更新 1.修改服务器的hostname [root@mexihq ~]# hostname [root@mexihq ~]# hostnamectl set-hostname xxx P ...
- 腾讯面试Android高级岗,居然被一个多线程基础面倒了?
前言 一个在深圳从事开发五年的老友一个月前从原公司辞职后,昨天去腾讯总部面试Android高级岗,一面的时候,自我介绍后,陆陆续续问了很多问题,有着五年的从业经验很多项目开发的技术问题都回答的很通顺, ...
- Leetcode周赛165
目录 找出井字棋的获胜者 思路 代码 不浪费原料的汉堡制作方案 思路 代码 统计全为 1 的正方形子矩阵 思路 代码 分割回文串 III 思路 代码 找出井字棋的获胜者 思路 模拟. 代码 class ...