C结构填充。巢状结构

C结构填充。巢状结构,c,compiler-construction,struct,padding,C,Compiler Construction,Struct,Padding,32位和64位机器上的填充不同。我不知道为什么。 据我所知,填充应如下所示: struct Y{ int int_one; int int_two; void * pointer; } struct X{ char char_one; char char_two; struct Y y_structures[20]; } 0x0字符\u一个 0x1字符2 0x4 y_结构[0]。int_one 0x8 y_结构[0]。int_two 0x12 y_结构[

32位和64位机器上的填充不同。我不知道为什么。 据我所知,填充应如下所示:

struct Y{
  int int_one;
  int int_two;
  void * pointer;
}

struct X{
    char char_one;
    char char_two;
    struct Y y_structures[20];
 }
0x0字符\u一个
0x1字符2
0x4 y_结构[0]。int_one
0x8 y_结构[0]。int_two
0x12 y_结构[0]。指针

32位上的结构与上述类似,但在64位机器上,
char\u two
y\u结构[0]的地址之间的差异为7字节。我认为它应该是3个字节,因为在
char\u two
之后要对齐的类型是
y\u结构[0]
的int,在两种体系结构上它的大小都是4。请帮忙

问题不在于int,而是指针。指针在64位计算机上的大小为8字节,因此它们必须从内存地址mod 8开始

 0x0 char_one <br>
 0x1 char_two <br>
 0x4 y_structures[0].int_one <br>
 0x8 y_structures[0].int_two <br>
 0x12 y_structure[0].pointer <br>

所以必须有6个填充字节。这在32位机器上是不必要的,因为指针只有4个字节。

32/64位系统之间存在差异:32位系统仍将8字节变量与32位边界对齐。64位系统将对齐长整数和双字节到8字节的边界。

您还必须记住,某些体系结构需要数据对齐(仅当地址对齐时才能访问数据)。它可以是32位体系结构,例如,您可以使用4个字符元素和16字节大小的结构。

只是好奇,您使用什么工具来检测填充量?真正的问题是:您为什么关心?如果你只是想学习,好吧。但是,如果要编写可移植代码,请不要编写依赖于特定填充的代码。结构定义后缺少分号。否,在32位计算机上,8字节变量也将以8的倍数对齐,请参阅:问题编号6Ravi是正确的。数据类型fpos\u t、off\u t和long long是32位可执行文件中自然对齐规则的例外。尽管它们都是8字节(64位)类型,但它们在4字节(32位)边界上对齐。双工也是如此,请检查System V x86 ABI。(第28页:图3-1):区别仅适用于英特尔平台的32位与64位ABI。在许多其他类型的硬件上,
double
是一个8字节的量,必须与8字节边界对齐,无论编译是针对该平台上的32位还是64位。英特尔的行为在各种CPU类型中都是反常的。在这种情况下,您可能是正确的,不要假设64位的值总是8,32位的值总是4。C标准没有这样的限制,它来自于硬件的设计。
0x0 char_one
0x1 char_two
0x8 y_structures[0].int_one
0x12 y_structures[0].int_two
0x16 y_structure[0].pointer
0x24 y_structures[1].int_one
0x28 y_structures[1].int_two
0x32 y_structure[1].pointer
...