什么是结构体的字节对齐现象程序员,咱都用代码说话,先上 code:
(说明:以下代码均在 arm 平台上,使用 keil 进行编译测试)
#define offset_of(type, member) ((size_t) &((type *)0)-member) //上面这个宏定义主要用于显示结构体成员变量相对结构体起始地址的偏移
typedef structstu1{ int a; char b; int c;}stu1;
void main(){ log_info(rnrn====== struct test ======rnrn); log_info(offset_of(stu1,a):t%dn,offset_of(stu1,a)); log_info(offset_of(stu1,b):t%dn,offset_of(stu1,b)); log_info(offset_of(stu1,c):t%dn,offset_of(stu1,c)); log_info(sizeof(stu1) :t%dn,sizeof(stu1)); return ;}
对于上面的运行结果,对字节对齐不了解的同学可能会疑惑,c的偏移量怎么会是8呢?不应该是 5 吗?
结构体的大小怎么会是12呢?不应该是 9 吗?
不了解的同学可能会这样理解:
c的偏移量是sizeof(int)+sizeof(char) = 5
结构体stu1占用的内存大小应该是sizeof(int)+sizeof(char)+sizeof(int)=9。
通过下图所示的stu1的内存结构可以知道,编译器对变量存储进行了一个特殊处理。
为了提高cpu的存储速度,编译器对一些变量的起始地址做了对齐处理。
在默认情况下,编译器规定各成员变量存放的起始地址相对于结构体的起始地址的偏移量,必须为该变量的类型所占用的字节数和编译器编译过程中采用的字节对齐数两者中最小值的整数倍。
有点绕,比如stu1 结构体中,变量 c 类型为 int,也就是占用 4 字节,编译器采用 4 字节对齐,因此偏移量必须是 4 的整数倍。
typedef structstu2{ int a; char b; char c int d;}stu2;再比上面的 stu2中,如对于变量 c,其类型为 char ,占用 1 字节,编译器采用 4 字节对齐,因此 它被分配的偏移量需要是 1 的整数倍,在上面的结构体 stu2 中,c 的偏移量为 5。
如图:
现在来分析前面的代码
假定a的起始地址为0,它占用了4字节,接下来的空闲地址就是4,是1的倍数,满足要求,所以b存放的起始地址是4,占用一个字节,接下来的空闲地址为5。c也是char变量,占用1字节, 因此可以放在地址 5 上面。
接下来看地址 6,对于 d,它占用了 4 个字节,同时需要注意的是,编译器默认按照结构体中占有内存最大的类型所占用的字节数进行字节对齐。在此结构体中占用内存最大的为整型,占用4字节,所以在此取两者的最小值4,6 并不是4的整数倍,所以向后移动,找到离6最近的8作为存放d的起始地址,d也占用4字节,最后结构体的大小为12。
需要注意的就是,变量b和 c后面2字节的存储空间是由编译器自动填充的,其中没有存储任何有用的信息。
宏电地灾监测预报预警系统精准实现对地质灾害监测信息采集
瞬态输出12W的3W AC/DC电源模块,拒绝被迫式功率冗余
荣耀50系列新配色荣耀密码亮相,探索未来之美
让AI走进课堂!保伦电子itc未来教学AI分析平台智慧捕抓教学数据
蓝宝石正式发布RadeonVII显卡 整卡功耗依然为300W
什么是结构体的字节对齐现象
主板电源回路
EMC检测所需资料和步骤
【RA2L1开发实践】-触摸按键控制舵机
苹果A14处理器采用台积电5nm将于2020年亮相
2019年的智能建筑是怎样发展的
比特币交易所Mt Gox的债权人现在可以申请索赔证明
微机消谐装置的作用 微机消谐装置的常见故障
智能液晶人工气候箱的功能特点
金融领域生物识别技术的发展具有方向性意义
什么是薄膜电容器?读完让你豁然开朗
IBM最新全球调研:零售消费体验满意度普遍较低,中国消费者对使用人工智能购物的兴趣强烈
完整的传感器到位解决方案简化了工业数据采集系统设计
哈佛研发出可用于捕获水母的超软机器人抓手
元宇宙离我们还有多远?