#include <stdio.h>
#include <string.h>
#include <malloc.h>
struct Student {
char name[100];
int id;
char major[50];
char address[200];
};
int main()
{
struct Student st;
strcpy(st.name, "Chuck");
st.id = 20001;
strcpy(st.major, "Computer Science");
strcpy(st.address, "1st Street");
printf("%d %d %d %d %d\n", sizeof(st), sizeof(st.name),sizeof(st.id), sizeof(st.major), sizeof(st.address));
return 0;
}
输出为356 100 4 50 200。 为什么sizeof(st)356,而不是354? 我尝试了这个没有int,输出是350 100 50 200,所以我假设问题在整数。
答案 0 :(得分:7)
这是由struct
成员之间的填充造成的。填充是确保每个数据成员正确aligned in memory所必需的。确切的对齐要求取决于您的架构。
因此,您不能假设struct
的大小等于其成员大小的总和。
答案 1 :(得分:1)
结构中的每个非第一个字段可以在间隙(或填充)之前。编译器正在添加间隙以满足处理器和ABI约定的需要。
您应该信任编译器,它正在按照实现的要求布置struct
。
有些编译器提供了扩展来改变或改进结构的布局,例如: aligned
或packed
的GCC type attributes。
不要将struct
内的填充和间隙视为一个问题,而是作为资产:编译器会非常努力地满足处理器,ABI惯例等......
大多数编译器不会对结构中的字段进行重新排序(GCC过去常常使用很少有用的优化,但是已经删除了优化,因为有时它会受到影响 - 例如使用LTO)。
如果您关心struct
大小,如果您不关心字段的顺序,您可以巧妙地重新排序。但最密集的顺序可能取决于架构。
int
是32位或更大的大小和对齐而不是char
(即使这是非常常见的)。它为此目的提供<stdint.h>
和int32_t
。我怀疑如果编译16位机器int
- s是16位(例如20世纪80年代使用Intel 8086处理器的原始PC AT,或者一些便宜的16位微控制器),你不会观察到任何填充或间隙