目录
结构体大小计算
结构体的成员在内存中的存储并不是连续存放的,而是要按照对齐规则对齐到某个位置上
结构体对齐规则
可以将结构体的内存布局想象成数组那样的连续存储并且每个字节都有对应的“下标”
- 结构体的第一个成员放在结构体偏移量为0的位置
- 结构体其他成员放在某个对齐数整数倍的偏移量处
- 若结构体内嵌套了结构体,那么该结构体成员的对齐数自身大小,就是该结构体成员中的最大对齐数
- 数组成员的对齐数自身大小为该数组存储的数据的类型
- 结构体的总大小为最大对齐数整数倍
细解规则
对齐数
结构体对齐数的大小是通过计算得到的
计算方式:该结构体成员的自身大小与编译器的默认对其数,取较小值
内存布局
为了便于理解可以将结构体的内存布局想象成,用偏移量将内存划分成一块一块且连续的小空间,就如同数组的内存布局那样。每快小空间的大小是一字节
偏移量
所谓的偏移量就是指相对于结构体空间的首地址偏移了多少字节,这里的偏移量可以理解为数组的下标
补充
- 第一个成员放在偏移量为0的位置上,而其他成员根据自身对齐数和当前偏移量来决定对齐到那个偏移量处
- 每个编译器的默认对齐数都是不一样的,VS的默认对齐数是8, Linux-gcc则没有默认对齐数
- 这里的对齐数自身大小指的就是自身大小
- 最大对齐数为结构体所有成员对齐数,取最大值
- 结构体的总大小必须是最大对齐数的整数倍,如果不是结构体的大小要自动对齐最大对齐数的整数倍
一图胜千言
例子一
在VS2019的环境下结构体s1在内存中的存储:
成员a作为第1个成员放在偏移量为0的位置上。
成员b的对齐数是4,(默认对齐数是8,自身大小是4,取较小值)b可以存放在偏移量为4的整数倍的位置上,结合当前偏移量,向下跳过三个字节空间存放在偏移量为4的位置上。
成员c这对齐数是1,(默认对齐数是8,自身大小是1,取较小值) C可以存放在偏移量为1的整数倍的位置上,结合当前偏移量,存放在偏移量为8的位置上。
最后当前结构体总大小是9个字节,最大对齐数是4,自动对齐到最大对齐数的整数倍上结果是12,那结构体的总大小为12个字节。
例子二
在VS2019的环境下结构体s2在内存中的存储,已知s1大小为8,最大对齐数是4:
成员a作为第1个成员,放在偏移量为0的位置上,向下占用八个字节。
成员b的对齐数是4,放在偏移量为8的位置上,向下占用四个字节。
成员c的对齐数是1,放在偏移量为12的位置上,向下占用四个字节。
最后结构体的大小是16个字节,是最大对齐数的整数倍,那结构体S2的大小就是16个字节。
联合体大小计算
联合体的内存特点是所有成员公用一块空间
联合体存储规则
- 联合体的大小是最大的成员的大小
- 当联合体最大成员的大下不是最大对齐数的整数倍时,联合体的大小要对齐到最大对齐数的整数倍
注:联合体对齐数的求法与结构体对齐数的求一样