结构体数据成员对齐的意义
许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的起始地址的值是某个数k的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus)。这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度。比如这么一种处理器,它每次读写内存的时候都从某个8倍数的地址开始,一次读出或写入8个字节的数据,假如软件能保证double类型的数据都从8倍数地址开始,那么读或写一个double类型数据就只需要一次内存操作。否则,我们就可能需要两次内存操作才能完成这个动作,因为数据或许恰好横跨在两个符合对齐要求的8字节内存块上。

结构体对齐包括两个方面的内容
1. 结构体总长度
2. 结构体内各数据成员的内存对齐,即该数据成员相对结构体的起始位置

结构体大小的计算方法和步骤
1. 将结构体内所有数据成员的长度值相加,记为sum_a;
2. 将各数据成员为了内存对齐,按各自对齐模数而填充的字节数累加到和sum_a上,记为sum_b。对齐模数是#pragma pack指定的数值以及该数据成员自身长度中数值较小者。该数据相对起始位置应该是对齐模式的整数倍。
3. 将和sum_b向结构体模数对齐,该模数是#pragma pac指定的数值和结构体内部最大的基本数据类型成员长度中数值较小者。结构体的长度应该是该模数的整数倍。

结构体大小计算举例
在计算之前,我们首先需要明确的是各个数据成员的对齐模数,对齐模数和数据成员本身的长度以及pragma pack编译参数有关,其值是二者中最小数。如果程序没有明确指出,就需要知道编译器默认的对齐模数值。下表是Windows XP/DEV-C++和Linux/GCC中基本数据类型的长度和默认对齐模数。

  charshortintlongdoublelong double
Windows长度1244812
模数124484
Linux长度1244812
模数124444