为什么我的工会规模比我预期的要大?

时间:2011-08-27 04:39:50

标签: c++ unions

当我打印像这样的联盟的大小时:

union u {
  char c[5];
  int i;
} un;

使用:

int _tmain(int argc, _TCHAR* argv[])
{
    printf("size of union = %d ",sizeof(un));
    return 0;
}

我使用Visual C ++得到了8的答案,但我预计5.为什么?

嗯,对于同样的例子, 我做了这样的事情:

int i1 = 0x98761234;
un.i = i1;
printf("\n un.c[0] = %x ",un.c[0]);
printf("\n un.c[1] = %x ",un.c[1]);
printf("\n un.c[2]= %x ",un.c[2]);
printf("\n un.c[3] = %x ",un.c[3]);
printf("\n un.c[4] = %x ",un.c[4]);
printf("size of union = %d ",sizeof(un));

我得到了像

这样的结果
un.c[0] = 34;
un.c[1] = 12;
un.c[2] = 76;
un.c[3] = ffffff98;

为什么在un.c [3]

有6fs

5 个答案:

答案 0 :(得分:11)

sizeof运算符生成变量或类型的大小,包括分隔该类型数组中元素所需的任何填充,以便所有内容仍然正确对齐。由于你的联盟有一个int成员,它需要4字节对齐,所以它的“自然”大小会向上舍入到下一个4字节的倍数。


ffffff98是因为您正在使用已签名的char进行编译。将%x与非unsigned int的参数一起使用会导致未定义的行为;你所看到的有时被称为 sign-extension 。您将别名的结果0x98重新解释为char,即-104。这保留了升级到int的价值(这称为默认参数促销),当-104别名为unsigned int时,0xffffff98为{{1}} }}。

答案 1 :(得分:3)

你的联盟的对齐必须是其任何成员的最大对齐。这是4.因此,联合的大小必须与该大小对齐。它本来可以是5(因为c是联合中最大的成员),但是由于整个联合的对齐是4,所以联合的大小填充为8。

请注意,这仅适用于VC ++。该标准没有特别要求。虽然它确实允许实现根据需要填充类型,VC ++会这样做。 GCC可以做一些不同的事情,可以使用编译时开关来改变这种行为。

答案 2 :(得分:3)

enter image description here编译器为对齐添加了几个字节

答案 3 :(得分:1)

编译器可以在任何想要结构,联合和类的地方添加填充来加速内存访问。你正在看到它的影响。对于Visual C ++,填充通常是最大成员类型大小的倍数。在这个例子中,最大的成员是一个int,因此它用3个未使用的字节填充联合,使总大小为8。

答案 4 :(得分:0)

感谢您的建议。我尝试了很多例子并且看起来如此  联合大小相当于 (最大元素的大小)+填充(取决于所使用的最高数据类型的大小)。