【问题标题】:are pad lengths different for each element in a struct? [duplicate]结构中每个元素的填充长度是否不同? [复制]
【发布时间】:2012-11-10 16:56:43
【问题描述】:

可能重复:
C struct sizes inconsistence

对于以下程序,我想获取结构的大小。但是,它的大小是 12 而不是4*4=16。这是否意味着每个元素都可以对齐到不同的焊盘编号?就像 int 和 4 和 short 和 2,但在这种情况下 char 应该有 1。

谢谢。

#include <stdio.h>

struct test{
int a;
char b;
short c;
int d;

};

struct test A={1,2,3,4};

int main()
{

    printf("0X%08X\n",&A.a);
    printf("0X%08X\n",&A.b);
    printf("0X%08X\n",&A.c);
    printf("0X%08X\n",&A.d);
    printf("%d\n",sizeof(A));

}

结果是:

0X00424A30
0X00424A34
0X00424A36
0X00424A38
12

【问题讨论】:

    标签: c


    【解决方案1】:

    是的,每种类型的对齐方式都不相同。您的每个变量都应正确对齐,即它们的地址应为一定大小的倍数。通常的规则(对于 Intel 和 AMD 等)是每种数据类型都按自己的大小对齐。假设 x86 架构,它似乎就在这里:

    • 0X00424A30:结构的首地址。
    • 0X00424A34:第一个成员之后的 4 个字节(可能是 sizeof(int))。 char 需要对齐1,所以这里不需要填充。
    • 0X00424A36:在第二个成员之后 2 个字节。 short 要求对齐为 2,因此有 1 个字节的填充。
    • 0X00424A38:在第二个成员之后 2 个字节。 int 需要对齐 4,但地址已经是 4 的倍数。所以没有填充字节。

    无论如何,这不是可移植的假设:C 标准在这里没有强制任何内容。它只允许在成员之间和结构末尾填充字节。

    顺便说一句,您应该使用以下格式:

    • %p 和指针类型转换;
    • %zu%usizeof 的类型转换。

    【讨论】:

    • 能否详细说明您想到的类型转换,尤其是对于sizeof 返回的printf()ing 值?
    • 为了避免使用类型转换的未定义行为,例如(unsigned int),存在溢出风险,但参数类型与格式%u 匹配。对于指针,需要在此类可变参数函数中强制转换为 (void *)
    • 在 AMD64 上,size_t 的大小与 unsigned int 的大小不同,因此带有 %u 的 printf 将期望不同大小的值,并且可能无法正常工作。最好使用长度修饰符来告诉 printf 参数的实际大小(例如,使用 %hu 表示 unsigned short)。
    • @che:你在说谁?
    • @che:不管怎样,有了类型转换,就没有问题了(正如我所说的溢出除外)。
    【解决方案2】:

    是的。请注意,填充取决于实现,因此在不同平台上可能会有所不同。 C99 spec 第 6.7.2.1 节仅指出可能在结构成员之间及其末端进行填充。要制作可移植的程序,您不应该对填充的长度做出任何假设。

    【讨论】:

      【解决方案3】:

      是的,每种类型都有自己的对齐限制。

      T 类型的对齐限制永远不会比要求与sizeof(T) 的倍数的地址对齐更严格,因为数组T arr[2] 的两个元素需要立即相互跟随而无需额外填充使arr[1] 正确对齐。 允许编译器使用不太严格的对齐要求。

      例如,

      • char 对象必须是字节对齐的(定义为 sizeof(char) == 1
      • short 对象通常是两字节对齐的(使用 sizeof(short) == 2),但在某些架构上也可以是字节对齐的
      • int 对象通常是四字节对齐的(sizeof(int) == 4),但在某些架构上也可能是两个甚至一个字节对齐
      • struct 类型通常要求对齐等于其成员中最严格对齐类型的对齐要求(有时最小对齐 > 1)。

      在构建结构时,所有成员都必须正确对齐,相对于结构的开头,第一个成员的偏移量为 0。为此,编译器可能必须在成员之后插入填充以获得下一个成员正确对齐。

      【讨论】:

      • “结构类型...通常至少对齐 4 个字节”——真的吗?我一直和你在一起,但是有很多编译器的struct Foo { char a; }; 导致sizeof(struct Foo) &gt; 1
      • @SteveJessop:由于我没有支持该声明的日期,因此我在回答中削弱了它。
      【解决方案4】:

      是的。因为Packing and byte alignment 一般的答案是compilers are free to add padding between members for alignment purpose

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-06-09
        • 2021-04-24
        • 1970-01-01
        • 2019-09-16
        • 2014-09-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多