1
 #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,所以我认为问题出在整数上。

4

2 回答 2

7

这是由于struct成员之间的填充。填充对于确保每个数据成员在内存中正确对齐是必要的。确切的对齐要求取决于您的架构。

因此,您不能假设 a 的大小struct等于其成员大小的总和。

于 2013-03-29T06:36:52.783 回答
1

结构中的每个非第一个字段之前都可以有一个间隙(或填充)。编译器正在添加空白以满足您的处理器和 ABI 约定的需要。

您应该信任编译器,它是按照实现的要求进行布局struct的。

一些编译器提供扩展来改变或改进结构的布局,例如GCC的类型属性alignedor packed

不要将 a 内部的填充和间隙struct视为问题,而是将其视为资产:编译器非常努力地满足处理器、ABI 约定等......

大多数编译器不会对结构中的字段重新排序(GCC 曾经有一个很少有用的优化可以做到这一点,但该优化已被删除,因为有时它会受到伤害 - 例如使用 LTO)。

如果您关心struct大小并且不关心字段的顺序,您可以巧妙地重新排序它们。但最密集的顺序可能取决于架构。

顺便说一句,C 标准甚至不保证 anint是 32 位或更大的大小和对齐方式char(即使这很常见)。它提供<stdint.h>int32_t为此目的。int我怀疑如果为-s 为 16 位的 16 位机器(例如 1980 年代带有 Intel 8086 处理器的原始 PC AT,或一些便宜的 16 位微控制器)编译,您不会观察到任何填充或间隙。

于 2013-03-29T06:37:33.737 回答