简体   繁体   English

C结构的数据对齐

[英]Data Alignment for C struct

There is a problem (3.45) in CS:APP about the byte offsets of all fields in the following struct. CS:APP中存在关于以下结构中所有字段的字节偏移的问题(3.45)。

struct {
  int    *a;
  float  b;
  char   c;
  short  d;
  long   e;
  double f;
  int    g;
  char   *h;
} rec;

Here is the answer from the book, which gives c a three bytes padding, d a two bytes padding and g a four bytes padding. 下面是从书,这给出了答案c一个三个填充字节, d一个两个字节填充和g的四个字节的填充。

field  size  offset
-----  ----  ------
a      8     0
b      4     8
c      1     12
d      2     16
e      8     24
f      8     32
g      4     40
h      8     48

And here is my solution, which only gives c a one byte padding and g a four bytes padding. 这里是我的解决方案,只给c一个字节填充和g四个字节填充。

field  size  offset
-----  ----  ------
a      8     0
b      4     8
c      1     12
d      2     14
e      8     16
f      8     24
g      4     32
h      8     40

So, what's the problem with my solution? 那么,我的解决方案有什么问题? It seems to fit the alignment rule (edit* the "rule" here is just a simplified concept summaries by myself, It's not completed or general), all object's offset is a multiple of the size of object. 它似乎符合对齐规则(编辑*这里的“规则”只是我自己的简化概念摘要,它没有完成或一般),所有对象的偏移量是对象大小的倍数。

Would be very thankful for any explanation. 非常感谢任何解释。

Given the sizes of objects shown and alignment rules that say each of these objects must be aligned to a multiple of its size, then, when the structure is laid out with only the padding required for alignment, the offsets should be as shown in Tetrau's solution. 给定显示的对象的大小和对齐规则,表明每个对象必须与其大小的倍数对齐,然后,当结构布局时只需要对齐所需的填充,偏移量应如Tetrau解决方案中所示。 The book solution is incorrect. 书中的解决方案不正确。

The offsets shown in Tetrau's solution are in fact the offsets produced by Apple LLVM 10.0.1 with Clang 1001.0.46.4 compiling for x86-64; Tetrau解决方案中显示的偏移实际上是Apple LLVM 10.0.1产生的偏移,Clang 1001.0.46.4为x86-64编译; the output from the program below is: 以下程序的输出是:

0
8
12
14
16
24
32
40
48
struct foo {
  int    *a;
  float  b;
  char   c;
  short  d;
  long   e;
  double f;
  int    g;
  char   *h;
} rec;


#include <stddef.h>
#include <stdio.h>


int main(void)
{
    printf("%zu\n", offsetof(struct foo, a));
    printf("%zu\n", offsetof(struct foo, b));
    printf("%zu\n", offsetof(struct foo, c));
    printf("%zu\n", offsetof(struct foo, d));
    printf("%zu\n", offsetof(struct foo, e));
    printf("%zu\n", offsetof(struct foo, f));
    printf("%zu\n", offsetof(struct foo, g));
    printf("%zu\n", offsetof(struct foo, h));
    printf("%zu\n", sizeof rec);
}

Note 注意

The rule that an object requires alignment to a multiple of its size is fine for this exercise, but it should be noted it is not a general rule. 对象需要与其大小的倍数对齐的规则对于此练习是好的,但应该注意,这不是一般规则。 A machine might have some eight-byte object but have only a bus and other memory access characteristics that are four bytes wide, so it would only care about four-byte alignment at most for any object. 一台机器可能有一些8字节的对象,但只有一个总线和其他4字节宽的内存访问特性,因此它只关心任何对象的最多四字节对齐。 Or a structure member might be another structure that is, say, nine bytes in size (such as struct bar { char x[9]; } ), but its alignment requirement would not be nine bytes. 或者结构成员可能是另一个结构,例如,大小为9个字节(例如struct bar { char x[9]; } ),但它的对齐要求不是9个字节。

The answer depends on the compiler, platform and compile options. 答案取决于编译器,平台和编译选项。 Some examples: 一些例子: 在此输入图像描述

https://godbolt.org/z/4tAzB_ https://godbolt.org/z/4tAzB_

The author of the book does not understand the topic I afraid. 这本书的作者不理解我害怕的话题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM