为什么short在C中的结构中存储为4个字节?

我有以下两种结构:

问题是sizeof(Content)返回160.结构由11个短路,6个整数,76个字符,7个浮点数,1个双精度组成,总共增加到158个字节。 我已计数三次,仍有2个字节的差异。

typedef struct TIME_T { short year,mon,day; short hour,min,sec; } TIME; typedef struct { int no; char name[20]; char Code[10]; char DASType[10]; short wlen; float VLtd; int samp; int comp; int locationID; short TranMode; char TranIns[12]; short TimerMode; char ClkType[12]; float ClkErr; float lat; float lon; float alt; float azimuth,incident; short weight; short veloc; int oritype; char seismometer[12]; double sens; TIME start_time; int record_samples; } Content; 

我写了一小段代码来打印结构中每个变量的位置,突然我发现float wlen需要4个字节。 我的代码如下:

 int main(void) { Content content; printf("Sizeof Content: %d\n", sizeof(content)); printf("Sizeof int content.no: %d\n", (int)&content.name - (int)&content.no); printf("Sizeof char[20] content.name: %d\n", (int)&content.Code - (int)&content.name); printf("Sizeof char[10] content.Code: %d\n", (int)&content.DASType - (int)&content.Code); printf("Sizeof char[10] content.DASType: %d\n", (int)&content.wlen - (int)&content.DASType); printf("Sizeof short content.wlen: %d\n", (int)&content.VLtd - (int)&content.wlen); printf("Sizeof float content.VLtdL %d\n", (int)&content.samp - (int)&content.VLtd); printf("Sizeof int content.samp: %d\n", (int)&content.comp - (int)&content.samp); printf("Sizeof int content.comp: %d\n", (int)&content.locationID - (int)&content.comp); printf("Sizeof int content.locationID: %d\n", (int)&content.TranMode - (int)&content.locationID); printf("Sizeof short content.TranMode: %d\n", (int)&content.TranIns - (int)&content.TranMode); printf("Sizeof char[12] content.TranIns: %d\n", (int)&content.TimerMode - (int)&content.TranIns); printf("Sizeof short content.TimerMode: %d\n", (int)&content.ClkType - (int)&content.TimerMode); printf("Sizeof char[12] content.ClkType: %d\n", (int)&content.ClkErr - (int)&content.ClkType); printf("Sizeof float content.ClkErr: %d\n", (int)&content.lat - (int)&content.ClkErr); printf("Sizeof float content.lat: %d\n", (int)&content.lon - (int)&content.lat); printf("Sizeof floatcontent.lon: %d\n", (int)&content.alt - (int)&content.lon); printf("Sizeof floatcontent.alt: %d\n", (int)&content.azimuth - (int)&content.alt); printf("Sizeof floatcontent.azimuth: %d\n", (int)&content.incident - (int)&content.azimuth); printf("Sizeof floatcontent.incident: %d\n", (int)&content.weight - (int)&content.incident); printf("Sizeof short content.weight: %d\n", (int)&content.veloc - (int)&content.weight); printf("Sizeof short content.veloc: %d\n", (int)&content.oritype - (int)&content.veloc); printf("Sizeof int content.oritype: %d\n", (int)&content.seismometer - (int)&content.oritype); printf("Sizeof char[12] content.seismometer: %d\n", (int)&content.sens - (int)&content.seismometer); printf("Sizeof double content.sens: %d\n", (int)&content.start_time - (int)&content.sens); printf("Sizeof TIME content.start_time: %d\n", (int)&content.record_samples - (int)&content.start_time); printf("Sizeof int content.record_samples: %d\n", sizeof(content.record_samples)); getchar(); return 0; } 

输出如下:

 Sizeof int content.no: 4 Sizeof char[20] content.name: 20 Sizeof char[10] content.Code: 10 Sizeof char[10] content.DASType: 10 Sizeof short content.wlen: 4 **Sizeof float content.VLtdL 4** Sizeof int content.samp: 4 Sizeof int content.comp: 4 Sizeof int content.locationID: 4 Sizeof short content.TranMode: 2 Sizeof char[12] content.TranIns: 12 Sizeof short content.TimerMode: 2 Sizeof char[12] content.ClkType: 12 Sizeof float content.ClkErr: 4 Sizeof float content.lat: 4 Sizeof floatcontent.lon: 4 Sizeof floatcontent.alt: 4 Sizeof floatcontent.azimuth: 4 Sizeof floatcontent.incident: 4 Sizeof short content.weight: 2 Sizeof short content.veloc: 2 Sizeof int content.oritype: 4 Sizeof char[12] content.seismometer: 12 Sizeof double content.sens: 8 Sizeof TIME content.start_time: 12 Sizeof int content.record_samples: 4 

编译器是MSVC8,没有定义UNICODE,没有定义其他宏。 这是x86。

我试着在gcc版本3.4.4中编译相同的代码,输出是一样的。 Sizeof short content.wlen: 4

任何人都可以向我解释这个吗?

提前致谢。

编辑:谢谢你的回答! 我现在知道了。

简短回答: 对齐

只是通过添加其所有组件的大小,您无法计算出结构的大小 – 允许编译器在字段之间插入填充,并且经常这样做。

对齐 – 在32位架构上,以32位块传递内存效率更高。 实际上你不会通过存储16位的短路来保存任何存储器,因为它仍然是相关的32位字的一部分。

你没有计算字段的大小,而是它们之间的“距离”,所以我猜你所看到的是结构中的字对齐。

是否在结构中添加另一个短尺寸会扩大尺寸,还是保持相同? 我的赌注是保持相同的大小。

两个编译器都在努力保持你的结构8字节对齐(我推测),所以一些字段将被“扩展”以占用额外的空间; 该字段上的实际操作将表现为“适当”大小。

如果编译器发现访问将更方便,那么结构成员通常在4字节边界上对齐。 char出现类似的行为。

您可以尝试通过将短路放在一起来优化结构的内存占用,以便两个连续的短路使用单个32位字。 不要忘记仔细检查编译结果。

根据C标准,内存中的每个本机类型都必须与其大小对齐,但与您的问题没有直接关系。 你应该研究的是结构包装。

正如dfa所说,这是由于对齐。 一个可以帮助减小结构尺寸的“好习惯”就是按照它们各自的尺寸(实际上是它们的个体对齐,但尺寸通常足够好)来命令它的成员从最大的成员开始。

这并非总是如此,但大部分时间都是如此。

看看pohole,Poke-a-Hole的缩写。 它是用于在结构中查找孔的DWARF2工具之一,由于对齐规则,孔是成员之间的空间,可用于新结构条目或重新组织以减小大小。

在该程序的作者Arnaldo Carvalho de Melo的这篇LWN文章中阅读更多相关内容。

在网上找不到很多教程,但是在CERN的这个wiki页面有点帮助。