为什么要有内存对齐
平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
结构体内存对齐规则介绍
结构体在内存中存储的时候,会存在一个内存对齐的现象
内存对齐规则:
结构体的第一个成员存放在与结构体变量偏移量为0的地址处(也就是结构体第一个成员存放在结构体首地址处)
除第一个成员外的其他成员需要对齐到对齐数的整数倍地址处(这里的地址是相对于结构体来说的)
对齐数:每个编译器可能会有一个默认对齐数,这个默认的对齐数与该成员大小(字节大小)的较小值,就是这个成员的对齐数,如果没有默认对齐数,成员的自身大小就是默认对齐数
(VS的默认对齐数是8,linux环境下是没有默认对齐数的,即自身大小就是对齐数)
结构体的总大小(总字节数)为结构体成员的最大对齐数(每个成员的对齐数,不是编译器的默认对齐数)的整数倍
对于嵌套结构体的情况,嵌套的结构体需要对齐到自己的成员的最大对齐数的整数倍处,结构体的整体大小就是所有成员的最大对齐数(含嵌套结构体的对齐数)的整数倍
在设计结构体的时候,让占用空间小的成员尽量集中在一起。
可以计算结构体成员相对于起始位置的偏移量
使用offsetof宏
计算结构体成员相对于起始位置的偏移量
写法:offsetof(结构体类型名,成员名)
返回值是size_t无符号整型数,返回的是结构体成员相对于起始位置的偏移量
头文件<stddef.h>
修改编译器默认对齐数
将编译器的默认对齐数修改为()中的值
写法:#pragma pack(对齐数)
本文探讨了内存对齐的重要性,包括平台移植性和性能提升的原因。详细介绍了结构体内存对齐的基本规则及其对整体内存布局的影响,并提供了计算成员偏移量的方法及如何调整编译器的默认对齐设置。
280

被折叠的 条评论
为什么被折叠?



