为什么我的结构元素带有填充字节?
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:
请参阅此内存转储。在填充结构元素之前,我已经 memset
用 p
的
填充了整个 t_outer
结构:
- 红色区域是
member1
- 蓝色区域是
member2
- 绿色区域是
member3
- 黄色区域标记了
dbl1
在 member3
中的位置
约束条件
- 编译器是VS2012
other_struct
的实际结构在这里无关紧要,它是一个 40 字节大小的 4 字节对齐结构
- 我确实不想要针对该行为(重新排序、打包等)的任何解决方法,但要解释为什么会发生这种情况。
VS2012 文档 describe its padding behavior。特别是,他们指定 struct
的对齐要求是其任何成员的最大对齐要求。成员 member3
的类型 t_inner
有一个类型 double
的成员,具有 8 字节对齐要求,因此 member3
整体具有 8 字节对齐要求(并且,此外,t_outer
有 8 字节对齐要求)。 member2
和 member3
之间需要填充以获得 member3
.
的 8 字节对齐
so that dbl1 is aligned on an 8-byte border
当然可以。但是,如果结构本身也没有与 8 对齐,则对齐保证意味着 bupkis。这是 通常 由编译器对数据部分和堆栈帧的地址选择提供的保证。或者内存分配器。都保证至少对齐到8。
但是当你将结构嵌入 s_outer 时,那 4 个字节的填充 before member3(不是在 member2 之后)需要获得对齐保证。
另请注意,结构可以在最后一个成员之后进行填充。当结构存储在数组中时,可能需要确保成员仍然对齐。同样的道理。
我对结构元素的内存对齐感到困惑。考虑这两个结构:
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:
请参阅此内存转储。在填充结构元素之前,我已经 memset
用 p
的
t_outer
结构:
- 红色区域是
member1
- 蓝色区域是
member2
- 绿色区域是
member3
- 黄色区域标记了
dbl1
在member3
中的位置
约束条件
- 编译器是VS2012
other_struct
的实际结构在这里无关紧要,它是一个 40 字节大小的 4 字节对齐结构- 我确实不想要针对该行为(重新排序、打包等)的任何解决方法,但要解释为什么会发生这种情况。
VS2012 文档 describe its padding behavior。特别是,他们指定 struct
的对齐要求是其任何成员的最大对齐要求。成员 member3
的类型 t_inner
有一个类型 double
的成员,具有 8 字节对齐要求,因此 member3
整体具有 8 字节对齐要求(并且,此外,t_outer
有 8 字节对齐要求)。 member2
和 member3
之间需要填充以获得 member3
.
so that dbl1 is aligned on an 8-byte border
当然可以。但是,如果结构本身也没有与 8 对齐,则对齐保证意味着 bupkis。这是 通常 由编译器对数据部分和堆栈帧的地址选择提供的保证。或者内存分配器。都保证至少对齐到8。
但是当你将结构嵌入 s_outer 时,那 4 个字节的填充 before member3(不是在 member2 之后)需要获得对齐保证。
另请注意,结构可以在最后一个成员之后进行填充。当结构存储在数组中时,可能需要确保成员仍然对齐。同样的道理。