为什么结构内的内存对齐会发生变化?

eck*_*kes 1 c memory windows alignment visual-studio-2012

上一个问题中,我了解到当具有 8 字节对齐的结构嵌入到另一个具有 4 字节对齐的结构时,在8 字节对齐的结构之前需要填充。

明白了。

至少我以为我理解了。

VS 2012 文档说:

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

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

typedef struct s_inner {
  unsigned long ul1;
  double        dbl1;
  fourth_struct s4;
  unsigned long ul2;
  int           i1;
} t_inner;
Run Code Online (Sandbox Code Playgroud)

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

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

内存转储

t_inner从地址开始1B8

  • 1B8: 被unsigned long填充,因为该结构是 8 字节对齐的
  • 1C0:double占用8字节
  • 1C8fourth_struct如下,它有4字节对齐

到现在为止,一切都如预想的那样。但现在里面的对齐方式切换了t_inner:在地址上1E8,我希望找到这里unsigned long,用 4 个字节填充,以便下面的内容int也在 8 个字节上对齐。但似乎对齐现在已经改变,因为unsigned long携带填充字节。相反,以下内容int采用 4 字节对齐方式放置。

为什么里面有对齐开关t_inner?这里应用哪条规则?

Jas*_*sen 5

我希望该结构的所有成员都是 8 字节对齐的,因为 double 是 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; 
Run Code Online (Sandbox Code Playgroud)

由于双精度结构本身的对齐方式为 8。