【c语言】字节对齐
字节对齐在C语言内存管理扮演关键的角色,之前对这一概念有些模糊,最近发现在汇编角度去看这一概念,可能更容易一些
1.什么是字节对齐?
对于现代计算机而言,当内存中需要被读写的数据,其所在地址满足“自然对齐”时,CPU 通常 能够以最高的效率进行数据操作。而所谓自然对齐,是指被操作数据的所在地址为该数据大小 的整数倍。
2.为什么要进行字节对齐?
首先,对于处理器架构而言,访问数据时通常是根据不同数据类型访问特定的内存地址,处理器更擅长处理最低有效位字节(lsb)为数据大小整数倍的内存块,这样可以大大提高内存的访问效率。
其实,目前处理器对非对齐数据访问性能消耗已经微不足道,字节对齐更需要注意的场景反而是在不同设备通信过程中。因为在不同的处理器架构中默认字节对齐大小可能不一致,这就导致同一组数据,在不同机器之间传输时,解析存在问题从而导致数据访问错误。
2.如何对齐?
如果在浏览器搜索字节对齐这一概念,通常作者会给出以下几个结论:C/C++ struct union 对齐方式与#pragma pack()宏定义
数据类型自身的对齐值:char-1\short-2\int-4...
指定对齐值:#pragma pack(x)预处理指令, x为对齐值,记得使用#pragma pack()结束
结构体或者类的自身对齐值:成员中长度最大值
上面情况都存在时,对齐值为指定对齐值与自身对齐值中的最小值
3.从汇编角度看字节对齐
如果按照传统str(这里是结构体变量名有些歧义😁)结构体内存空间大小为:1+4+3=7Bytes。
而真实大小为填充过的12Bytes,从右边可以看出,rbp寄存器存放栈帧开始处的高地址,栈空间中地址从高地址向低地址增长,字符a存放在rbp-12地址处,填充三字节,占4字节;整形b存放在rbp-8地址处,占4字节;短整型c存放在rbp-4地址处,同样填充2字节空白,占用4字节。
实际共占4+4+4=12Bytes。