我知道由于对齐,char和int被计算为32位体系结构上的8个字节,但是我最近遇到了一种情况,即sizeof运算符报告了一个带有3个short的结构为6个字节.代码如下:
#includeusing namespace std ; struct IntAndChar { int a ; unsigned char b ; }; struct ThreeShorts { unsigned short a ; unsigned short b ; unsigned short c ; }; int main() { cout< 编译器:g ++(Debian 4.3.2-1.1)4.3.2.这真的让我很困惑,为什么不对包含3个短裤的结构进行对齐?
1> slacker..:那是因为
int
是4个字节,并且必须与4字节边界对齐.这意味着struct
包含a的ANYint
也必须与至少4个字节对齐.另一方面,
short
是2个字节,并且只需要对齐到2个字节的边界.如果struct
包含short
s不包含任何需要更大对齐的内容,struct
则也将对齐为2个字节.
2> nos..:这真的让我感到困惑,为什么不对t执行对齐
你想要它有什么对齐方式?
短裤可以在2字节边界上对齐,没有不良影响(假设这里常见的x86编译器......).因此,如果你创建一个数组
struct ThreeeShorts
,那个大小为6的结构很好,因为这样一个数组中的任何元素都将从2字节边界开始.你
struct IntAndChar
包含一个int,int需要4字节对齐,所以如果你创建一个struct IntAndChar
大小必须为8 的数组,下一个元素要在4字节边界上对齐.如果我们不考虑数组,如果
struct IntAndChar
长度为5个字节则无关紧要,编译器只会在创建一个堆栈时从4字节边界开始分配它,或者将其用作另一个结构中的复合成员.你总是可以通过执行sizeof(arrayofT)/ sizeof(T)来获取数组中元素的数量,并且保证数组元素相邻存储,这样第n个元素就可以通过步进N*sizeof(arrayelementtype)来检索. )从开始的字节,这是你看到结尾填充结构的主要原因.
3> AnT..:我不知道你在哪里得到的想法
char
或被int
计算为"8字节".不,每种类型都是根据其大小计算的:在32位平台上char
为1,int
为4(不是8,而是4).每种类型的对齐要求通常与其大小相同(尽管不一定如此).因此,当结构包含相同类型的成员时,该结构的总大小通常是其成员大小的精确总和:3
char
s 的结构大小为3,结构为2int
s将有8号.显然
short
你的平台上的类型有2号,所以,预计3个短裤的结构大小为6,这正是你所观察到的.但是,当您的结构包含不同类型的成员时,不同类型的对齐要求之间的差异就会起作用.如果下一个字段的对齐要求比前一个字段的对齐要求更严格,则编译器可能必须在这些字段之间添加一些填充字节(以正确对齐下一个成员),这将影响结构的最终大小.此外,编译器可能必须在结构的最后一个成员之后添加一些额外的填充字节,以满足数组中的对齐要求.
例如,结构如下所示
struct S { char c; int i; };由于
char
成员之后需要3个填充字节,因此很可能在您的平台上占用8个字节.char
计数,计为1,int
为4,它们之间额外的3个填充字节使其为8.还要注意,这可能很容易引入结构的最终大小对声明成员的顺序的依赖性.例如,这种结构
struct S1 { char c1; int i; char c2; };在你的平台上可能有12个,而这个
struct S2 { int i; char c1; char c2; };将只占用8个字节.最后一个例子旨在说明结构的最终大小不能用每个成员"计数"的字节数来表示.成员之间的关系也很重要.