c-为什么一个字符只有一个填充字节(在32位机器上)



关于数据填充的教程说,下面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除。

相关内容

最新更新