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

标签 c struct alignment

这是来自计算机系统:程序员的视角,第 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/

相关文章:

c - 管道类型消息检测

c - 从 GSocket 接收垃圾

c - C 中的 Makefile 包

c - 为什么用OpenMP生成随机数没有提速?

swift - 当 Swift 结构是存储属性时,可以在堆上分配它吗?

go - 在 golang 中扩展包结构

c# - 'locate' C# 结构在哪里?/如何在项目中组织结构

css - eclipse网页编辑器: div's not in line

python - 我如何堆叠按钮而不是在 Tkinter 中将它们排队?

html - 带有长单词的 CSS 居中文本