所以我在C中定义了一个结构:
struct example {
int ex1;
u_long ex2;
float ex3;
float ex4;
};
因此,所有示例成员的大小为20,但示例的大小为24,这意味着正在添加填充。我真正不了解的是为什么以及在哪里。
打扰一下,如果我的术语不正确,但我认为因为它是4字节干净(即所有成员的大小%4 == 0),所以不需要添加填充。是因为我运行x86需要8字节清理,还是仅仅是常态?
然后我真的不知道填充的位置在哪里,我会假设在u_long周围,但我不确定。
答案 0 :(得分:3)
结构通常也在末端填充,因此结构的总大小可以被具有最大对齐的成员所需的对齐方式整除。
在您的情况下,u_long
需要8个字节的对齐,并且在第一个成员结束后放置4个字节,以使其地址位于8字节边界上。结构的总大小变为24,因此最后不需要任何额外的填充。
最后填充确保在顺序数组中布局时,第二个元素不会破坏某些成员的对齐。
答案 1 :(得分:1)
我认为因为它是4字节干净(即所有成员的大小%4 == 0),所以不需要添加填充。
这不是一个安全的假设。 C对于struct
表示可以添加多少填充或其中的位置几乎没有限制。它什么都没说,什么时候或为什么。这些选择取决于编译器。
是因为我正在运行x86需要8字节清理,还是仅仅是常态?
你假设是" 8字节清洁"与填充有关。它可能会,但同样,这是一个实施决定。
一般来说,编译器会插入填充以确保所有成员都可以对齐,以便在struct
数组的每个元素中实现最佳访问。这可能需要在成员之间或最后或两者之间填充。但这仍然是一个实施考虑因素。如果您想了解您使用的特定C实现如何解决问题,那么您需要查阅其文档。
答案 2 :(得分:0)
这是一个测试,在一台特定的机器上运行,您的结果可能会有所不同:
$ cat ul.c
#include <stdio.h>
struct example {
int ex1;
unsigned long ex2;
float ex3;
float ex4;
};
struct example ex;
int main ( void ) {
printf("Size:\t%zd\n", sizeof(ex));
printf("ex @\t%p\n", &ex);
printf("ex1 @\t%p\n", &ex.ex1);
printf("ex2 @\t%p\n", &ex.ex2);
printf("ex3 @\t%p\n", &ex.ex3);
printf("ex4 @\t%p\n", &ex.ex4);
return 0;
}
$ ./ul
Size: 24
ex @ 0x600940
ex1 @ 0x600940
ex2 @ 0x600948
ex3 @ 0x600950
ex4 @ 0x600954
此处的填充位于ex1和ex2之间。