问题描述
A tutorial on data padding 表示下面 C 结构体中 char c
后面的 int i
需要 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,不能被 2 整除。这会导致未对齐的内存访问。
为了防止这种情况,我们在 char c
之后添加了 1 个字节的填充。填充 1 个字节后,short s
将存储 ar 0x0006,可被 2 整除。