02.结构体内存对齐
Last updated
Last updated
奇怪了,Misa
和Light
,明明内存成员相同,怎么一个16,一个24呢?下面我们先了解一个东西:内存对齐
第一个数据成员从偏移量为0的地方开始,占用该成员大小的字节。
如Misa,以double
开始,那么就是0-7
以后每个成员的存储起始位置都要从该成员大小
或者成员的子成员
大小的整数倍
开始
子成员,如:
数组、结构体等
如果一个结构体A
内,有结构体B
作为成员。则该成员要从其内部最大元素大小
的整数倍地址
开始存储.
结构体总大小,必须是其内部最大成员的整数倍,不足要补齐。
大小(字节)
8
1
4
2
使用空间
0.1.2.3.4.5.6.7
8
12.13.14.15
16.17
double
8字节
从0开始,占用0-7
char
1字节
从1的整数倍开始,8满足条件,占用8
int
4字节
从4的整数倍开始,上一个末位为8,那么先后找,就找从12开始,占用12-15
short
2字节
从2的整数倍开始,上一个末位为15,那就从16开始,暂用16-17
总大小
这些成员暂用了0-16共17个字节
按照第三条对齐规则,向上取最大成员8的倍数,结果就是0-23,即24字节。和实际输出相同
大小(字节)
8
4
1
2
使用空间
0.1.2.3.4.5.6.7
8.9.10.11
12
14.15
double
8字节
从0开始,占用0-7
int
4字节
从4的倍数开始,合适的是8,暂用8-11
char
1字节
从1的倍数开始,合适的是12,占用12
short
2字节
从2的倍数开始,合适的是14,占用14-15
总大小
成员占用了0-15
按照原则3,需要是最大成员8的倍数,即16字节。和实际输出相同
如此我们可以发现,对于结构体来说,内部成员的顺序直接影响了结构体占用的空间。
大小(字节)
8
4
1
2
成员最大8
成员最大8
使用空间
0.1.2.3.4.5.6.7
8.9.10.11
12
14.15
...
...
由于比较长,Girl和Boy我们拿出来做
从8的整数倍开始,即16
大小(字节)
8
1
4
2
使用空间
16.17.18.19.20.21.22.23
24
28.29.30.31
32.33
从8的整数倍开始,即40
大小(字节)
8
4
1
2
使用空间
40.41.42.43.44.45.46.47
48.49.50.51
52
54.55
占用0-55
最大成员8,则Together总大小为56。与输出一致。
并不用,这里内部做了优化了的。后面我们会单独对这里进行研究。
不是所有硬件平台都能访问任意地址上的任意数据的
某些硬件平台只能在某些地址处理某些特定的数据类型,否则会抛出硬件异常
数据结构,尤其是栈,应该尽可能的在自然边界上对齐
因为未来访问未对齐的内存,处理器需要做两次内存访问;而对其的内存访问只需要一次
内存对齐是一个以空间换时间
的过程,为了使CPU更高效的读写数据,提升性能
结构体
优点:所有成员可共存,全面
缺点:内存分配存在浪费,不管用不用,全部分配
联合体
优点:内存使用更加精细灵活,节省空间
缺点:成员互斥
同时只有一个成员可以得到这块内存的使用权(对该内存的读写),各变量共用一个内存首地址
一个union变量的总长度至少能容纳最大的成员变量,而且要满足是所有成员变量类型大小的整数倍
举个例子:游戏中的控制角色移动