关于数据填充的教程说,下面C结构中int i
后面的char c
需要1个填充字节。
struct test2
{
int i;
// 4 bytes
char c;
// 1 byte
// 1 padding byte. <-- question here
short s;
// 2 bytes
};
我想理解为什么不是3字节填充,因为在这种情况下,内存访问是在32位上?
每个成员的对齐才是最重要的。考虑每种类型的对齐要求。对于int
,在您的情况下,它是4
字节。对于char
,它自然是1
。来一辆short
怎么样?在您的体系结构中,它似乎是2
字节。我们希望每个成员都能根据自己的对齐要求进行对齐。
由于int
是第一个成员,我们不需要任何填充(但这确实会影响整个struct
的大小(。然后,我们有一个char
,它有最宽松的要求,所以我们不需要为它垫。然后是short
。它需要与2个字节对齐。我们目前的偏移量为5个字节,因此我们需要一个填充字节来正确对齐short
。总而言之,这给了我们8个字节,而且这也符合整个结构的对齐方式,所以最后不需要额外的填充。
一般来说,结构的最小尺寸将通过将构件从最强对齐要求排序到最弱来实现。这不一定是获得最小尺寸的唯一订单,但可以保证没有其他订单会更小。
从未对齐内存访问
当您尝试读取N个字节的数据时,会发生未对齐的内存访问从一个不能被N整除的地址开始(即addr%N!=0(。例如,从地址0x10004读取4字节的数据可以,但从地址0x10005读取4字节的数据将是未对齐的内存访问。
int
的大小为4个字节,short
的大小为2个字节,而char
的大小为1个字节(64位系统(。
让我们假设起始地址为0x0000。
因此,int i
从0x0000到0x0003。char c
存储在0x0004(因为,地址可被1整除(。
假设char c
之后没有1字节的填充,则short s
将存储在0x0005,该0x0005不可除以2。这会导致未对齐的内存访问。
为了防止这种情况,我们在char c
之后添加了1个字节的填充。在填充1个字节之后,short s
将被存储为0x0006,该值可被2除。