sizeof如何计算结构的大小

时间:2010-04-17 19:30:10

标签: c++ alignment sizeof

我知道由于对齐,char和int被计算为32位体系结构上的8个字节,但是我最近遇到了一个情况,即sizeof运算符报告了一个带有3个short的结构为6个字节。代码如下:

#include <iostream>
using namespace std ;

struct IntAndChar
{
    int a ;
    unsigned char b ;
};


struct ThreeShorts
{
    unsigned short a ;
    unsigned short b ;
    unsigned short c ;
};


int main()
{
    cout<<sizeof(IntAndChar)<<endl; // outputs '8'
    cout<<sizeof(ThreeShorts)<<endl; // outputs '6', I expected this to be '8'
    return 0 ;
}

编译器:g ++(Debian 4.3.2-1.1)4.3.2。这真的让我感到困惑,为什么不对包含3个短裤的结构强制对齐?

6 个答案:

答案 0 :(得分:22)

那是因为int是4个字节,并且必须与4个字节的边界对齐。这意味着包含struct的任何int也必须与至少4个字节对齐。

另一方面,short是2个字节,并且只需要对齐到2个字节的边界。如果包含struct的{​​{1}}不包含任何需要更大对齐的内容,则short也将与2个字节对​​齐。

答案 1 :(得分:15)

  

这真让我感到困惑,为什么不对t执行对齐

您希望它具有哪种一致性?

短裤可以在2字节边界上对齐,没有不良影响(假设这里常见的x86编译器......)。因此,如果您创建一个struct ThreeeShorts数组,那么大小为6的结构就可以了,因为这样一个数组中的任何元素都将从2字节边界开始。

你的struct IntAndChar包含一个int,ints想要4字节对齐,所以如果你创建一个struct IntAndChar的数组,那么大小必须是8,以便下一个元素在4字节边界上对齐。

如果我们不考虑数组,如果struct IntAndChar长度为5个字节就没那么重要,编译器只会在你创建一个堆栈时从4字节边界开始分配它,或者使用它作为另一个结构中的复合成员。

您可以通过执行sizeof(arrayofT)/ sizeof(T)来获取数组中元素的数量,并保证数组元素相邻存储,这样第n个元素可以通过步进N *来检索sizeof(arrayelementtype)从一开始的字节,这是你看到结尾填充结构的主要原因。

答案 2 :(得分:6)

我不知道您将charint计算为“8字节”的想法。不,每个类型都是根据其大小计算的:char为1,int为32位平台上的4(不是8,而是4)。每种类型的对齐要求通常与其大小相同(尽管不一定如此)。

因此,当结构包含相同类型的成员时,该结构的总大小通常是其成员大小的精确总和:结构为3 {{ 1}} s的大小为3,两个char的结构大小为8。

显然,您平台上的int类型的大小为2,因此,预计3个短裤的结构大小为6,这正是您所观察到的。

但是,当您的结构包含不同类型的成员时,不同类型的对齐要求之间的差异就会起作用。如果下一个字段的对齐要求比前一个字段的对齐要求更严格,则编译器可能必须在这些字段之间添加一些填充字节(以正确对齐下一个成员),这将影响结构的最终大小。此外,编译器可能必须在结构的最后一个成员之后添加一些额外的填充字节,以满足数组中的对齐要求。

例如,结构如下

short
由于在struct S { char c; int i; }; 成员之后需要3个填充字节,

很可能在您的平台上占用8个字节。注意,char计为1,char计为4,并且它们之间的额外3个填充字节使其为8。

另请注意,这可能很容易将结构的最终大小的依赖性引用到声明成员的顺序。例如,这个结构

int
您平台上的

可能大小为12,而这个

struct S1 {
  char c1;
  int i;
  char c2;
};

只占用8个字节。最后一个例子旨在说明结构的最终大小不能用每个成员“计数”的字节数来表示。成员之间的关系也很重要。

答案 3 :(得分:2)

它完全取决于实现,但是假设您的系统可以访问结构中的三个short中的任何一个而不用担心对齐,它可以访问任何short,因此可以访问任何数据成员,在ThreeShorts数组中,无需担心对齐。因此,不需要更严格地对齐结构。

对于IntAndChar示例,int可能大小为4,实现 与其对齐有关。要确保int数组中的每个IntAndChar成员都正确对齐,必须填充结构。

sizeof数组T[n]的确定义为sizeof(T) * n

答案 4 :(得分:1)

此链接应该有所帮助:http://en.wikipedia.org/wiki/Data_structure_alignment

ThreeShorts中,所有成员都是两个字节对齐的。

答案 5 :(得分:1)

是的,我有同样的问题。我有以下结构

struct Node{
    short digit;
    Node* next;
};
    cout<<":"<<sizeof(Node)<<":"<<sizeof(short)<<":"<<sizeof(Node*)<<endl;

这给了我:: 8:2:4 ??为什么结构的总和= 8,但个别元素不总结? 这是因为内存对齐,内存用额外的2个字节填充以进行对齐。 感谢