可能重复:
struct sizeof result not expected
Struct varies in memory size?
以下是在Ubuntu Server 11.10 for i386机器上编译的代码:
// sizeof.c
#include <stdio.h>
#include <malloc.h>
int main(int argc, char** argv){
printf("int's size: %d bytes\n", sizeof(int));
printf("double's size: %d bytes\n", sizeof(double));
printf("char's size: %d bytes\n", sizeof(char));
printf("\n");
printf("char pointer's size: %d\n", sizeof(char *));
printf("\n");
struct Stu{
int id;
char* name;
char grade;
char sex;
// double score;
};
printf("struct Stu's pointer's size : %d\n",sizeof(struct Stu *));
struct Stu stu;
stu.id=5;
stu.name="Archer";
stu.grade='A';
stu.sex='M';
printf("Stu(int,char*, char,char)'s size: %d bytes\n", sizeof(struct Stu));
printf("Stu(5,\"Archer\",'A','M')'s size: %d bytes\n",sizeof(stu));
}
编译:
`gcc -o sizeof sizeof.c`
输出:
int's size: 4 bytes
double's size: 8 bytes
char's size: 1 bytes
char pointer's size: 4
struct Stu's pointer's size : 4
Stu(int,char*, char,char)'s size: 12 bytes
Stu(5,"Archer",'A','M')'s size: 12 bytes
我的问题是为什么struct Stu
的大小为12,而不是sizeof(int) + sizeof(char *) + sizeof(char) + sizeof(char) = 4 + 4 + 1 + 1 = 10. When you put a double member into
struct Stu ,
sizeof(struct Stu)`的大小为20。
答案 0 :(得分:4)
要计算用户定义类型的大小,编译器会考虑复杂的用户定义数据结构所需的任何对齐空间。这就是为什么C中结构的大小可以大于其成员大小的总和。例如,在许多系统上,以下代码将打印8:
参考http://en.wikipedia.org/wiki/Sizeof
假设您具有以下结构:
struct A1
{
char a[2];
int b;
};
你可以认为sizeof(A1)等于6,但事实并非如此。它等于8.编译器在成员'a'和'b'之间插入2个虚拟字节。
原因是编译器会将成员变量与包大小的倍数或类型大小的倍数对齐,以最小者为准。
visual studio中的默认包大小为8个字节。
'b'是整数类型,宽度为4个字节。 'b'将与2的最小值对齐,即4个字节。 “a”是1,2,3或4字节宽是无关紧要的。 'b'将始终在同一地址上对齐。
答案 1 :(得分:1)
数据必须正确对齐以获得不错的效率,因此编译器可以自由地在结构内部添加填充(除了开始之外的任何地方)。
通常,N字节类型(对于1,2,4,8,16字节)在N字节地址边界上对齐。
因此,对于32位编译,结构具有:
int id; // offset = 0, size = 4
char* name; // offset = 4, size = 4
char grade; // offset = 8, size = 1
char sex; // offset = 9, size = 1
double score; // offset = 16, size = 8
总大小为24.请注意,即使您将double
移动到结构的前面,或者移到结构的前面,或者移到名称之后,大小仍然是24,因为所有元素都是结构的数组必须正确对齐,因此将至少有6个字节的填充。 (有时,只需要在4字节边界上对齐一个double;然后填充将是2个字节而不是6个。)
即使没有double
成员,结构也必须是12个字节长,以便id
正确对齐数组中的额外元素 - 将有2个字节的填充。
有些编译器为编程人员提供了一条名为#pragma pack
或其左右的绳索,一些程序员有机会用这样提供的绳索悬挂自己。