【问题标题】:Why does the memory alignment change within a structure?为什么结构内的内存对齐会发生变化?
【发布时间】:2023-03-14 14:42:01
【问题描述】:

previous question 中,我learned 表示,当一个具有 8 字节对齐的结构嵌入到另一个具有 4 字节对齐的结构中时,需要在 8 字节之前进行填充对齐结构。

明白了。

至少我认为我理解了。

VS 2012 docs 说:

对于结构、联合和数组,对齐要求是其成员的最大对齐要求。

所以,如果我有这样的结构:

typedef struct s_inner {
  unsigned long ul1;
  double        dbl1;
  fourth_struct s4;
  unsigned long ul2;
  int           i1;
} t_inner;

我希望这个结构的所有成员都是 8 字节对齐的,因为 double 是 8 字节对齐的。

但我的内存转储向我展示了这一点:

t_inner从地址1B8开始:

  • 1B8unsigned long 被填充,因为结构是 8 字节对齐的
  • 1C0double 占用 8 个字节
  • 1C8: fourth_struct 紧随其后,它有 4 字节对齐

到目前为止,一切都按预期进行。但现在 t_inner 内部的对齐切换: 在地址1E8 上,我希望在这里只找到unsigned long,用4 个字节填充,以便下面的int 也对齐8 个字节。但似乎对齐方式现在已经改变,因为unsigned long 确实 not 携带填充字节。相反,下面的int 以 4 字节对齐放置。

为什么t_inner 内部的对齐切换?这里应用了哪条规则?

【问题讨论】:

  • 有人能解释一下反对意见吗???
  • 对否决票一无所知。我正要说那句话试图描述结构的对齐要求,而不是它的单个成员。但杰森已经描述过了。那里很受欢迎。
  • 这是一篇关于数据对齐的好文章...ibm.com/developerworks/library/pa-dalign也许你会发现它很有用:)
  • “当一个具有 8 字节对齐的结构嵌入到另一个具有 4 字节对齐的结构中时,需要在 8 字节对齐结构之前进行填充”。不可以。在内部struct 之前可能需要填充,也可能不需要填充,这取决于所有外部struct 的成员(包括内部struct)的对齐要求。外部struct 的对齐要求并没有直接影响,外部和内部structs 的对齐要求也不同。

标签: c windows visual-studio-2012 memory alignment


【解决方案1】:

我希望这个结构的所有成员都是 8 字节对齐的,因为 双精度是 8 字节 > 对齐的。

嗯,不。每个类型在结构内部都有自己的对齐方式,结构本身有一个对齐方式是最大的其内容的对齐方式。

aligned.    typedef struct s_inner {
      unsigned long ul1;        // 4-aligned
      double        dbl1;       // 8-aligned  (need 4 padding before this)
      fourth_struct s4;         // 4 aligned  size 32
      unsigned long ul2;        // 4 aligned  (no padding)
      int           i1;         // 4 aligned  (no padding)
      // no padding needed as struct is a multiple of 8 bytes
    } t_inner; 

由于双精度,结构本身具有对齐 8。

【讨论】:

  • 上升了。一个更极端的例子是 iSeries 上的指针类型结构成员,由于该平台如何管理指针有效性管理,它要求 16 字节对齐。可以想象,结构会迅速膨胀。任何减少填充和对齐的请求都是无效的(有充分的理由)。
猜你喜欢
  • 2020-07-14
  • 1970-01-01
  • 2017-09-28
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2017-08-22
  • 2018-04-08
相关资源
最近更新 更多