为什么我的结构元素带有填充字节?

Why does my structure element carry padding bytes?

我对结构元素的内存对齐感到困惑。考虑这两个结构:

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

typedef struct s_outer {
    other_struct    member1; /* 4-byte aligned, 40 bytes in terms of sizeof() */
    unsigned long   member2;
    t_inner         member3; /* see above */
} t_outer;

当我检查 t_outer 的内存布局时,我可以看到 member1 的元素是 4 字节对齐的,正如我所期望的那样。 member3 的内存布局也符合预期:ul1 附加了 4 个填充字节,因此 dbl1 在 8 字节边界上对齐(在 Win32 上正常)。

但是, 当我检查 member2 的内存布局时,我可以看到该成员附加了 4 个填充字节。 谁能解释为什么 member2 接收填充字节?我的期望是 member2 没有填充。


编辑 1: 请参阅此内存转储。在填充结构元素之前,我已经 memsetp

填充了整个 t_outer 结构:


约束条件

VS2012 文档 describe its padding behavior。特别是,他们指定 struct 的对齐要求是其任何成员的最大对齐要求。成员 member3 的类型 t_inner 有一个类型 double 的成员,具有 8 字节对齐要求,因此 member3 整体具有 8 字节对齐要求(并且,此外,t_outer 有 8 字节对齐要求)。 member2member3 之间需要填充以获得 member3.

的 8 字节对齐

so that dbl1 is aligned on an 8-byte border

当然可以。但是,如果结构本身也没有与 8 对齐,则对齐保证意味着 bupkis。这是 通常 由编译器对数据部分和堆栈帧的地址选择提供的保证。或者内存分配器。都保证至少对齐到8。

但是当你将结构嵌入 s_outer 时,那 4 个字节的填充 before member3(不是在 member2 之后)需要获得对齐保证。

另请注意,结构可以在最后一个成员之后进行填充。当结构存储在数组中时,可能需要确保成员仍然对齐。同样的道理。