每个字段都要放到内存地址编号(地址值) 自身的整数倍地址上去。
(这样理解也可以。 不用太纠结😀,就可以不用看下面的)。
为什么存在内存对齐
平台移植型好
不是所有的硬件平台都能访问任意地址上的数据;某些硬件平台只能只在某些地址访问某些特定类型的数据,否则抛出硬件异常,及遇到未对齐的边界直接就不进行读取数据了。
cpu处理效率高
从上图可以看出,对应两种存储方式,若CPU的读取粒度为4字节,
那么对于一个int 类型,若是按照内存对齐来存储,处理器只需要访存一次就可以读取完4个字节
若没有按照内存对其来读取,如上图所示,就需要访问内存两次才能读取出一个完整的int 类型变量
具体过程为,第一次拿出 4个字节,丢弃掉第一个字节,第二次拿出4个字节,丢弃最后的三个字节,然后拼凑出一个完整的 int 类型的数据。
32位 与 64位 程序 对齐 有区别。 一个默认是4字节 一个是8字节。
char 一个字节的,随便放。 大于1个字节的时候,需要注意对齐粒度了。禁止让一个多字节数据跨粒度了。
struct 前面的字段要对后面数据的地址编号的负责, 如果大于char了。 short 必须是2的倍数。 int 是4的倍数 double 是8的倍数。最后一个字段对下个结构体 开头位置负责。(结构体 放到数组中的时候 需要对齐)
https://blog.csdn.net/weixin_41453492/article/details/101318522
https://acl.readthedocs.io/en/latest/zhCN/ch2-cn.html
https://ksco.gitbooks.io/build-your-own-lisp/content/Basics.html
核心 #pragma pack(8) 这里不指定的话,就是默认值. 用该形式(权),确定怎么计算每个结构体中的变量具体地址. good (不含糊了.明确了.)
结构体默认对齐
规则
- 64位操作系统上64位编译器:默认8字节对齐
- 64位操作系统上32位编译器:默认8字节对齐
- 32位操作系统上32位编译器:默认4字节对齐
以下两点是对于64位操作系统上64位编译器:默认8字节对齐而言的,如果是4字节对齐,只需要将8改成4即可:
- 结构体整体本身安置在8字节对齐处,结构体对齐后的大小必须是8的倍数
- 结构体中每个元素占的字节大小是自身对齐参数的整数倍