x86-64中的结构中的数据对齐

时间:2018-11-09 02:19:43

标签: c struct alignment

    struct P1 { short i; int c; int *j; short *d; };
    struct P4 { char w[16]; char *c[2]; };
    struct P5 { struct P4 a[2]; struct P1 t; };

我有几个关于填充的问题。我了解到默认情况下会应用填充。

所以我认为结构P1的偏移量应该是

i    c    j    d    total    alignment
---------------------------------------
0    2    8    16    24         8

以及 P5结构

a    t    total    alignment
----------------------------
0    64     96        8

因为P4的总大小为32byte。 但是教科书的解决方案是不同的。我想我是对的。

解决方案建议

i    c    j    d    total    alignment
---------------------------------------
0    2    6    14    16         8


a    t    total    alignment
----------------------------
0    24     40        8

1 个答案:

答案 0 :(得分:1)

结构填充的确切细节由实现定义。但是,编译器的确倾向于将字段放置在适合其类型的对齐方式上。

假设8个字节的指针(假设您使用的是x86-64机器)是4个字节的int和2个字节的short,则大多数情况下您是正确的。 c中的P1字段为int,可能以4字节的偏移量开始,但其余字段的偏移量应相同。 P5的大小也只需为88(2个P4的大小为64,1 P1的大小为24),因为只需要8字节对齐即可,而不是16字节对齐。

给出以下代码:

printf("sizeof p1 = %zu\n", sizeof(struct P1));
printf("sizeof p4 = %zu\n", sizeof(struct P4));
printf("sizeof p5 = %zu\n", sizeof(struct P5));
printf("P1 offset: %zu, %zu, %zu, %zu\n",
    offsetof(struct P1, i), offsetof(struct P1, c),
    offsetof(struct P1, j), offsetof(struct P1, d));
printf("P4 offset: %zu, %zu\n",
    offsetof(struct P4, w), offsetof(struct P4, c));
printf("P5 offset: %zu, %zu\n",
    offsetof(struct P5, a), offsetof(struct P5, t));

我的带有gcc 4.8.5输出的x86-64 CentOS 7计算机:

sizeof p1 = 24
sizeof p4 = 32
sizeof p5 = 88
P1 offset: 0, 4, 8, 16
P4 offset: 0, 16
P5 offset: 0, 64

您正在使用的书似乎使用了4个字节的指针,并且假定没有对齐或打包的结构。

有关更多详细信息,请查看The Lost Art of Structure Padding