在C/C++中,字节对齐时内存分配的一种策略。
当分配内存时,编译器会自动调整数据结构的内存布局,使得数据成员的起始地址与其自然对齐边界相匹配。
字节对齐有助于提高内存访问速度,因为许多处理器都优化了对齐数据的访问。但是,这可能会导致内存中的一些空间浪费。
字节对齐的规则
1. 自然对齐边界
对于基本数据类型,其自然对齐边界通常为其大小。
例如,char 类型的自然对齐边界是 1 字节, short 为 2 字节。
2. 结构体对齐
结构体内部的每个成员都根据其自然对齐边界进行对齐。这样也就是可能在成员之间插入填充字节。
因此,结构体本身的总大小也会根据其最大对齐边界的成员进行对齐(比如结构体成员包含的最长类型为 int 类型,那么整个结构体要按照 4 的倍数对齐),以便在数组中正确对齐。
3. 联合体对齐
联合体的对齐边界取决于其最大对齐边界的成员。联合体的大小等于其最大大小的成员,因为联合体的所有成员共享相同的内存空间。
4. 编译器指令
可以使用编译器指令更改默认的对齐规则。这个命令是全局生效的,可以用于减少数据结构的大小,但可能会降低访问性能。
#pragma pack(push, 1) // 设置字节对齐为 1 字节,取消自动对齐
struct UnalignedStruct {
char a;
int b;
short c;
};
#pragma pack(pop) // 恢复默认的字节对齐设置
5. 对齐属性
在 C++11 及更高版本中,可以使用 alignas 关键字为数据结构或变量指定对齐要求。这个命令是对某个类型或者对象生效的。
例如: alignas(16) int x; 将确保 x 的地址是 16 的倍数。
6. 动态内存分配
大多数内存分配函数(如 malloc 和 new)会自动分配足够对齐的内存,以满足任何数据类型的对齐要求
大端字节序
高位字节存储在低地址处,低位字节存储在高地址处。
例如一个4字节的整数 0x12345678,在大端字节序的系统中,内存布局是 0x12 0x34 0x56 0x78。
大端字节序是符合人类阅读习惯的顺序。
小端字节序
低位字节存储在低地址处,高位字节存储在高地址处。
常见的使用场景
1. 网络传输
在网络传输过程中,通常使用大端字节序,也称为网络字节序,这是 TCP/IP 协议的规定,多字节数据在网络上传输时使用大端字节序。
因此,如果本地系统使用的是小端字节序,那么就需要在传输之前将其转换为大端字节序。
2. Linux
Linux 操作系统在不同硬件平台上可能使用不同的字节序。
3. Windows
Windows 操作系统主要运行在 x86 和 x86_64架构上,这些处理器使用小端字节序。
4. Mac
一般 Mac 都采用小端字节序。