【问题标题】:Why is there only 1 padding byte for a char (on a 32-bit machine)?为什么 char (在 32 位机器上)只有 1 个填充字节?
【发布时间】:2021-04-01 19:08:18
【问题描述】:

A tutorial on data padding 表示下面 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
};

鉴于在这种情况下内存访问是 32 位,我想了解为什么不是 3 字节填充?

【问题讨论】:

  • 我认为是因为在char 之后有short,尝试删除short,你应该看到sizeof(test2) 为8

标签: c memory-management padding


【解决方案1】:

每个成员的一致性是最重要的。考虑每种类型的对齐要求。对于int,在您的情况下,它是4 字节。对于char,自然是1short 怎么样?好吧,在您的架构上,它似乎是 2 字节。我们希望每个成员都根据自己的对齐要求对齐。

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

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

【讨论】:

    【解决方案2】:

    来自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将存储在不能被2整除的0x0005。这会导致内存访问不对齐。

    为了防止这种情况,我们在char c 之后添加了 1 个字节的填充。填充 1 个字节后,short s 将存储为 0x0006,可被 2 整除。

    【讨论】:

    • 谢谢。未对齐的内存访问是一个严重的问题还是只是一个良性问题?此外,既然编译器的工作似乎是确保我们的数据结构良好对齐,那么为什么首先会发生未对齐的内存访问?
    • @zell 查看此链接了解更多详情:developer.ibm.com/technologies/systems/articles/pa-dalign
    • 链接提供了未对齐内存访问影响的详细说明。
    • @zell 未对齐的内存访问--->需要更多的内存周期来进行读写。因此,它会减慢系统速度。
    猜你喜欢
    • 2013-07-24
    • 2021-08-22
    • 2023-02-02
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    相关资源
    最近更新 更多