C语言字节对齐
C语言字节对齐方式分为自然对齐和强制对齐两种。在结构体的大小的计算中,常会用到字节对齐的知识。
自然对齐
自然对齐规则
数据成员对齐规则
在默认情况下,结构体成员变量的存放起始地址相对于结构体的起始地址的偏移量为sizeof(类型)的倍数。
整体对齐规则
结构体总体大小必须为sizeof(最大类型)的整数倍。
自然对齐例子
struct one
{
char a;
int b;
long c;
double d;
};
sizeof(one) = sizeof(char) + 3 + sizeof(int) + sizeof(long) + 4 + sizeof(double) = 24;24为3 * sizeof(double),满足整体对齐规则。
强制对齐
通过下面指令指定按n字节强制对齐
#pragma pack(n) //指定以下代码为n字节对齐
···
···
#pragma pack() //恢复默认对齐方式
还可以通过下面的方式保存原有的对齐方式
#pragma pack(push) //保存现有的对齐方式
#pragma pack(n) //指定新的对齐方式
···
···
#pragma pack(pop) //恢复原来的对齐方式
···
···
强制对齐规则
数据成员对齐规则
结构体成员变量的存放起始地址相对于结构体的起始地址的偏移量为min{ sizeof(类型), n }的整数倍。
整体对齐规则
结构体总体大小必须为min{ sizeof(类型), n }的整数倍。
强制对齐例子
#pragma pack(4)
struct two
{
char a;
int b;
long c;
double d;
char e;
};
在四字节对齐情况下struct two的大小,
sizeof(two)= sizeof(char) + 3 + sizeof(int) + sizeof(long) + sizeof(double) +sizeof(e) + x ;
sizeof(two) = 21 + x;
由于sizeof(two)必须是 min {sizeof(double),4 }的整数倍,也就是4的整数倍 ,所以x = 3,故:
sizeof(two) = 24。
#pragma pack(2)
struct two
{
char a;
int b;
long c;
double d;
char e;
};
同样是struct two,如果是按照2字节对齐,则
sizeof(two) = sizeof(char) + 1 + sizeof(int) + sizeof(long) + sizeof(double) + sizeof(char) + x;
sizeof(two) = 19 + x;
由于sizeof(two)必须是min {sizeof(double), 2 }的整数倍,也就是2的整数倍,所以x= 1,故:
sizeof(two) = 20。