【问题标题】:calculating the size of structure计算结构的大小
【发布时间】:2015-06-03 18:08:46
【问题描述】:

我正在研究结构成员对齐和结构填充概念的时候发现这个struct的大小...

struct node{
  int b;
  char a;
 };

... 是 8 个字节(即它包含 3 个字节的填充),而这个 struct ...

的大小
struct node{
  char a;
};

... 只有 1 个字节。为什么后者没有padding?

【问题讨论】:

  • 请在发帖前研究 C 填充规则。如果你这样做了,请说明你发现了什么以及为什么你仍然感到困惑。
  • 想想数组,node[N]
  • 是的,得到了​​答案!

标签: c struct padding


【解决方案1】:

Data structure alignment.

描述得很精彩here

假设你有这样的结构:

struct  {
    char a[3];
    short int b;
    long int c;
    char d[3];
    };

现在,您可能认为应该可以像这样将这个结构打包到内存中:

+-------+-------+-------+-------+
|           a           |   b   |
+-------+-------+-------+-------+
|   b   |           c           |
+-------+-------+-------+-------+
|   c   |           d           |
+-------+-------+-------+-------+

但是如果编译器像这样安排它,处理器上会容易得多:

+-------+-------+-------+
|           a           |
+-------+-------+-------+
|       b       |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           |
+-------+-------+-------+

在 ''packed'' 版本中,请注意您和我至少有点难以看到 b 和 c 字段是如何环绕的?简而言之,处理器也很难。因此,大多数编译器会像这样“填充”结构(好像带有额外的、不可见的字段):

+-------+-------+-------+-------+
|           a           | pad1  |
+-------+-------+-------+-------+
|       b       |     pad2      |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           | pad3  |
+-------+-------+-------+-------+

这篇文章解释了填充是如何完成的,而不是为什么这样做。请参考 hacks 的回答了解为什么这样做。

【讨论】:

  • 实际上您提供的链接解释了为什么需要填充,而不是何时以及如何完成。
  • 懒得重写了,所以就加了个P.S.到帖子。
【解决方案2】:

记住这两条填充规则:

  1. 仅当结构成员后跟具有更大对齐要求的成员或结构的末端时,才会插入填充。
  2. 最后一个成员填充了所需的字节数,因此结构的总大小应该是任何结构成员的最大对齐的倍数。

第二个结构中的成员a 后面没有任何成员或具有更大对齐的成员,它也是最大的对齐成员,这意味着--无填充。

阅读此answer 以获得更详细的说明。

【讨论】:

  • 知道了,谢谢你的链接。我不知道第二个事实。谢谢!!
  • 如果我说我有一个结构,它的一个成员是:int(4字节),另一个是double,在int之后会发生结构填充吗?根据规则我们知道结构体的总大小应该是 8 的倍数(double 的大小),但是即使我们不做任何填充,double 也会在 2 个周期内被读取。此外,关于对象数组,如果大小为 12 字节(无填充),下一个对象也将以最小周期数被读取,同样与 16 字节(有填充字节)相同。 Ideone 给出 12 作为这种结构的大小,而代码块 Dev 给出 16。哪个是正确的?
  • 我不明白你的问题?
  • 假设我们有一个有两个成员的结构,即 struct { int a; double b;} 结构 12 或 16 的大小是多少? Ideone 给出 12 个代码块,Dev 给出 16 个。
  • 看到这个:ideone.com/CTv8bs,它给出了 12,而在 CodeBlocks 和 Dev 上同样给出了 16。
【解决方案3】:

struct 成员的填充和对齐完全由编译器决定,除了第一个成员之前不能有任何填充。话虽如此,编译器通常会选择填充来实现对齐目的,因此特别是

  1. 同一结构的所有成员可以同时以最佳方式对齐,并且
  2. structs 的数组中,如果第一个数组元素的成员以最佳方式对齐,那么所有其他元素的成员也是如此。

根据这些和类似的要求,编译器通常会选择必要的最少填充量(理想情况下根本不需要填充)。如果不同的成员类型有不同的对齐要求,那么上述考虑要求将struct 表示填充为具有最严格对齐要求的成员大小的倍数。根据成员的类型及其顺序,它们可能还需要成员之间的填充。

【讨论】:

    猜你喜欢
    • 2019-05-08
    • 2011-02-09
    • 2014-10-04
    • 2017-04-26
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多