结构体字节对齐
字节对齐的作用和原因:
各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多。
1、基本数据类型对齐规则:数据类型对象的地址值能被其数据类型的大小整除。 eg. 满足int类型对象的地址addr % sizeof(int) = 0
2、结构体对齐规则:结构体的首地址能被其数据成员中数据类型最大的整除。
eg. struct S{
char a; 1byte
int b; 4byte
short c; 2byte
}
满足结构体首地址addr % sizeof(int)=0 (结构体中int类型最大,占4byte)
3、结构体内成员对齐规则:如下代码
#pragma pack(n)
struct S{
char a; 1byte
int b; 4byte
short c; 2byte
}
#pragma pack() //结束
将结构体中成员类型大小与n比较,选择较小的那个值进行对齐。
例如当n =2时。
char a 1byte<2byte,按1字节对齐。
int b 4byte>2byte,按2字节对齐。
short c 2byte=2byte,按2字节对齐。
注:
#pragma pack
的主要作用就是改变编译器的内存对齐方式。#pragma pack(n)
是最基本的用法,其作用是改变编译器的对齐方式, 不使用这条指令的情况下,编译器默认采取#pragma pack(8)
也就是8字节的默认对齐方式,n值可以取(1, 2, 4, 8, 16)
中任意一值。
4、结构体总大小:size=min{最大数据成员,n};