sizeof(x)
返回2,针对以下结构体
struct s {
short c;
} x;
但对于结构
struct s {
short c;
char a;
} x;
sizeof(x)
返回 4
,为什么?
第二个结构体会占用一个填充字节(假设short类型长度��2字节,char类型长度为1字节)。那么第一个结构体不应该占用两个填充字节吗(因此长度为4字节)?
sizeof(x)
返回2,针对以下结构体
struct s {
short c;
} x;
但对于结构
struct s {
short c;
char a;
} x;
sizeof(x)
返回 4
,为什么?
第二个结构体会占用一个填充字节(假设short类型长度��2字节,char类型长度为1字节)。那么第一个结构体不应该占用两个填充字节吗(因此长度为4字节)?
short
大小为两个字节,需要两个字节的对齐。按定义,char
大小为一个字节,需要一个字节的对齐。struct s {short c;}
中:c
放在struct
的开头。开头永远不会有填充。
- 如果我们制作这些struct
的数组,则下一个struct s
将从第一次开始两个字节,并且它的成员 c 仍将位于两个字节的倍数处,因此对齐正确。
- 因此,我们不需要任何填充来使其正常工作。struct s {short c; char a;}
中:c
放在开头。
- a
放在c
后两个字节。这很好,因为只需要一个字节的对齐。
- 如果我们不添加任何填充,则struct
的大小为三个字节。然后,如果我们制作这些struct
的数组,则下一个struct s
将从开始处三个字节开始。
- 在第二个struct s
中,成员c
将位于三个字节的偏移处。这违反了short
的对齐要求。
- 因此,为了使这个struct
正常工作,我们必须添加一个字节的填充。这使总大小为四个字节。然后,在这些struct
的数组中,所有成员都将处于所需对齐方式的边界上。
即使你仅声明一个结构的单个对象,如struct s {short c; char a;} x;
,结构也总是布局为可用于数组。第一个结构体有一个大小为2的元素(假设 short
在您的系统上大小为2)。它就像直接拥有一个短数组。
第二个结构是一个特殊的东西:最好在偶数地址上访问 short
变量。如果我们没有填充,我们会得到以下结果:
struct s arr[5]; // an array
void * a = arr; // needed to reference it
接下来,
arr[0].c
存储在地址 a
。arr[0].a
存储在地址 a
+ 2 字节。arr[1].c
存储在地址 a
+ 3 字节!arr[1].a
存储在地址 a
+ 5 字节!由于希望将 arr[1].c
存储在偶数地址上,因此需要添加填充位。然后,
arr[1].c
存储在地址 a
+ 4 字节。arr[1].a
存储在地址 a
+ 6 字节。
int
,假设sizeof(int) > sizeof(short)
,编译器将不得不填充结构体末尾,使其对齐到sizeof(int)
的倍数。 - vgru