为什么sizeof()在64位cpu上有所不同?

时间:2009-06-04 16:46:37

标签: c

请考虑以下示例:

#include <stdio.h>
#include <inttypes.h>

struct A {
        uint32_t i1;
        uint32_t i2;
        uint32_t i3;
        uint64_t i4;
        uint32_t i5;
        uint32_t i6;
        uint32_t i7;
        uint64_t i8;
        uint32_t i9;
};

struct B {
        uint32_t i1;
        uint32_t i2;
        uint32_t i3;
        uint32_t i4;
        uint32_t i5;
        uint32_t i6;
        uint32_t i7;
        uint64_t i8;
        uint64_t i9;
};

int
main()
{
        struct A a;
        struct B b;

        printf("sizeof(a) = %u, sizeof(b) = %u\n", sizeof(a), sizeof(b));

        return 0;
}

输出是:

$ ./t2 
sizeof(a) = 56, sizeof(b) = 48
$ 

为什么它们在64位机器上有所不同?在32位平台上的结果是相同的:

$ ./t2
sizeof(a) = 44, sizeof(b) = 44

8 个答案:

答案 0 :(得分:22)

一些图表可以帮助您查看:

32位:

+----+----+----+----+----+----+----+----+----+----+----+
| i1 | i2 | i3 |   i4    | i5 | i6 | i7 |   i8    | i9 | Struct A
+----+----+----+----+----+----+----+----+----+----+----+

+----+----+----+----+----+----+----+----+----+----+----+
| i1 | i2 | i3 | i4 | i5 | i6 | i7 |   i8    |   i9    | Struct B
+----+----+----+----+----+----+----+----+----+----+----+

64位:

+---------+---------+---------+---------+---------+---------+---------+
| i1 | i2 | i3 |~~~~|    i4   | i5 | i6 | i7 |~~~~|   i8    | i9 |~~~~| Struct A
+---------+---------+---------+---------+---------+---------+---------+

+---------+---------+---------+---------+---------+---------+
| i1 | i2 | i3 | i4 | i5 | i6 | i7 |~~~~|   i8    |   i9    | Struct B
+---------+---------+---------+---------+---------+---------+
  • + :地址边界
  • :padding

答案 1 :(得分:8)

编译器通过边界(在编译尝试中不同)对齐struct成员。

添加

#pragma pack (1)

指令在源文件的开头并重试。

答案 2 :(得分:3)

因为它可以。编译器不需要在32位和64位模式之间使用相同的布局。它可以在需要时插入填充。您不应该首先依赖结构的精确布局。

原则上,它甚至可以在每次编译时更改填充。 (很难想象为什么编译器会这样做,但它被允许)

答案 3 :(得分:2)

64位整数必须放在64位内存边界上。因此,当在64位机器上创建结构A时,编译器在i3和i7之后粘贴一个4字节的填充空间 - 从而在那里增加了8个字节。

答案 4 :(得分:1)

由于元素之间的填充。

答案 5 :(得分:1)

这是由于结构对齐引起的:struct A有3个32位值,后跟64位值。无论前3个元素的打包如何,64位元素肯定不会在64位之间的边界之间开始(即占据两个独立的64位值的一半),因此在第3和第4个元素之间至少有32位填充。

答案 6 :(得分:0)

sizeof(b)是48,因为最后一个uint32占用了一个完整的64位(因为随后的uint64s与64位块对齐.sizeof(a)占用更多,因为前3个unit32s占用2个块,接下来的3个占用2个块,最后的uint32占用一个完整的64位块

答案 7 :(得分:0)

这是因为对齐。

平台上的64位整数可能需要64位对齐。

所以在混合结构中你有3个32位整数,在它们之后必须插入另一个32位填充以使64位整数正确对齐。

如果在64位字段之前插入偶数32位字段,则大小差异应该消失。