这是来自计算机系统:程序员的视角,第 3 版(全局版)第 311 页,第 3.9 节的教科书问题:
Practice Problem 3.44 (solution page 381)
For each of the following structure declarations, determine the offset of each field, the total size of the structure, and its alignment requirement for x86-64:
A.
struct P1 { short i; int c; int *j; short *d; };
...
D.
struct P4 { char w[16]; char *c[2]; };
E.
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的总大小是32字节。 但教科书上的解决方案却不同。我想我是对的。
解决方案建议
i c j d total alignment
---------------------------------------
0 2 6 14 16 8
a t total alignment
----------------------------
0 24 40 8
最佳答案
结构填充的具体细节是实现定义的。但是,编译器确实倾向于将字段放置在适合其类型的对齐位置。
假设 8 字节指针(假设您在 x86-64 机器上)4 字节 int
和 2 字节 short
,您大部分 正确。 P1
中的 c
字段是一个 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));
我的 x86-64 CentOS 7 机器,带有 gcc 4.8.5 输出:
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 .
关于c - x86-64 结构中的数据对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53218933/