微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么一个字符只有 1 个填充字节在 32 位机器上?

如何解决为什么一个字符只有 1 个填充字节在 32 位机器上?

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,自然是 1short 怎么样?好吧,在您的架构上,它似乎是 2 字节。我们希望每个成员都根据自己的对齐要求对齐。

由于 int 是第一个成员,我们不需要任何填充(但这确实会影响整个 struct 的大小)。然后,我们有一个 char,它的要求最宽松,所以我们不需要填充它。然后是 short。它需要对齐到 2 个字节。我们当前的偏移量为 5 个字节,因此我们需要一个填充字节来使 short 正确对齐。总而言之,这给了我们 8 个字节,并且也适合整个结构的对齐方式,因此最后不需要额外的填充。

一般来说,结构的最小尺寸将通过从最强到最弱的对齐要求对成员进行排序来实现。这不一定是获得最小尺寸的唯一顺序,但可以保证没有其他顺序会更小。

,

来自Unaligned Memory Accesses

当您尝试读取 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 整除。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。