最近碰到了有关于结构体成员对齐的问题,参考了一些资料之后,自己总结了以下内容,以备后用。
首先理解4个概念:
(1)数据类型自身对齐
type Alignment(变量存放的起始地址相对于结构体的起始地址的偏移量)
char 在字节边界上对齐
short 在双字边界上对齐
int and long 在四字节边界上对齐
float 在四字节边界上对齐
double 在八字节边界上对齐
(2)结构体或者类自身的对齐:其成员中自身对齐值最大的值。
(3)指定对齐值:由#pragma pack(value)指定的value值。
(4)数据类型、结构体和类的有效对齐值:自身对齐值和指定对齐值中最小的那个值var。
理解了这些概念之后,可以发现有效对齐值是最终决定数据存放地址方式的值。假设数据(包括成员数据和结构体或者类)最终存放的起始地址为Addr,则应该有“Addr%var=0”。
举例:
#pragma pack(1)
struct _test_pack_1{
char a;
int b;
short c;
}test_pack_1;
#pragma pack()
sizeof(test_pack_1)=7
解释:
以上代码中指定对齐值为1,成员变量a自身对齐为1,因此a的有效对其值为1;假设结构体test_pack_1从地址空间0x0开始存放,则a的起始addr=0x0,符合“0x0%1=0”;成员变量b自身对齐为4,因此b的有效对齐值为1,存放地址可以从0x1~0x4,符合“0x1%1=0";成员变量c自身对齐为2,因此有效对齐值为1,存放地址可以从0x5~0x6,符合“0x1%1=0";结构体test_pack_1存放地址为0x0~0x6,总共7个字节,结构体test_pack_1自身对齐值为其变量中最大值4,有效对齐值为1,符合“7%1=0",因此结构体test_pack_1最终存放地址为0x0~0x6,总共7个字节。
举例:
#pragma pack(2)
struct _test_pack_2{
char a;
int b;
short c;
}test_pack_2;
#pragma pack()
sizeof(test_pack_1)=8
解释:
以上代码中指定对齐值为2,成员变量a自身对齐为1,因此a的有效对其值为1;假设结构体test_pack_1从地址空间0x0开始存放,则a的起始addr=0x0,符合“0x0%1=0”;成员变量b自身对齐为4,因此b的有效对齐值为2,存放地址可以从0x2~0x5,符合“0x2%2=0";成员变量c自身对齐为2,因此有效对齐值为2,存放地址可以从0x6~0x7,符合“0x6%2=0";结构体test_pack_2存放地址为0x0~0x7,总共7个字节结构体test_pack_2自身对齐值为其变量中最大值4,有效对齐值为2,符合“8%2=0",因此结构体test_pack_2最终存放地址为0x0~0x7,总共8个字节。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。