用u_long填充C结构

时间:2016-01-08 18:33:57

标签: c struct padding

所以我在C中定义了一个结构:

struct example {
  int ex1;
  u_long ex2;
  float ex3;
  float ex4;
};

因此,所有示例成员的大小为20,但示例的大小为24,这意味着正在添加填充。我真正不了解的是为什么以及在哪里。

打扰一下,如果我的术语不正确,但我认为因为它是4字节干净(即所有成员的大小%4 == 0),所以不需要添加填充。是因为我运行x86需要8字节清理,还是仅仅是常态?

然后我真的不知道填充的位置在哪里,我会假设在u_long周围,但我不确定。

3 个答案:

答案 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之间。