对于以下程序,我想获得结构的大小。但是,它的大小变为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
答案 0 :(得分:1)
是的,每种类型都没有相同的对齐方式。您的每个变量都应正确对齐,即它们的地址应为特定大小的倍数。通常的规则(对于Intel和AMD,以及其他规则)是每种数据类型都按其自身大小对齐。假设x86架构,它似乎就在这里:
0X00424A30
:结构的第一个地址。 0X00424A34
:第一个成员之后的4个字节(可能是sizeof(int)
)。 char
需要1
的对齐方式,因此此处不需要填充。 0X00424A36
:第二个成员后的2个字节。 short
需要对齐2,因此有1个字节的填充。0X00424A38
:第二个成员后的2个字节。 int
要求对齐为4,但地址已经是4的倍数。因此没有填充字节。无论如何,它不是可移植的假设:C标准在这里不强迫任何东西。它只允许在你的成员之间和结构的末尾填充字节。
顺便说一下,您应该使用以下格式:
%p
和指针的类型转换; %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
。