3

可能重复:
C 结构大小不一致

对于以下程序,我想获取结构的大小。但是,它的大小是 12 而不是4*4=16. 这是否意味着每个元素都可以与不同的焊盘编号对齐?像int4 和short2 一样,但在这种情况下 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
4

4 回答 4

1

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

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

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

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

  • %p和指针的类型转换;
  • %zu%usizeof.
于 2012-11-10T17:01:01.040 回答
1

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

于 2012-11-10T17:05:40.093 回答
1

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

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

例如,

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

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

于 2012-11-10T17:06:04.223 回答
0

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

于 2012-11-10T17:03:35.197 回答