结构中每个元素的填充长度是否不同?

时间:2012-11-10 16:56:44

标签: c

  

可能重复:
  C struct sizes inconsistence

对于以下程序,我想获得结构的大小。但是,它的大小变为12而不是4*4=16。这是否意味着每个元素可以对齐不同的垫号?例如int为4,short为2,但在这种情况下,char应为1。

THX。

#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 个答案:

答案 0 :(得分:1)

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

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

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

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

  • %p和指针的类型转换;
  • {li> %zu%u使用sizeof进行类型转换。

答案 1 :(得分:1)

是。请注意,填充由实现决定,因此在各种平台上可能会有所不同。 C99 spec第6.7.2.1节仅说明可能在结构成员之间和结尾之间填充。要制作便携式程序,不应对填充的长度做任何假设。

答案 2 :(得分:1)

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

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

例如,

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

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

答案 3 :(得分:0)

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