【问题标题】:How padding is applied in the code?如何在代码中应用填充?
【发布时间】:2014-02-07 03:51:49
【问题描述】:

我从维基百科阅读了以下代码

struct MixedData
{
    char Data1;
    short Data2;
    int Data3;
    char Data4;
}md;
printf("%u    %u    %u    %u", &md.Data1, &md.Data2, &md.Data3, &md.Data4);

输出是:-

268624    268626    268628    268632

我无法理解在上述代码中每个数据成员之后如何应用填充?

【问题讨论】:

    标签: c structure padding


    【解决方案1】:

    来自here

    第一个元素是 char,它是一个字节对齐的,然后是 short 诠释。 short int 是 2 字节对齐的。如果短 int 元素是 在 char 元素之后立即分配,它将以奇数开始 地址边界。编译器会在后面插入一个填充字节 char 以确保 short int 将具有 2 的地址倍数(即 2 字节对齐)。

    这是你的结构的样子:

    +-------+-------+-------+-------+
    | Data1 |       |     Data2     |
    +-------+-------+-------+-------+
    |             Data3             |
    +-------+-------+-------+-------+
    | Data4 |       |       |       |
    +-------+-------+-------+-------+
    

    所以从 char 到 short 的填充是一个字节 =>

    268624 到 268625 是 Data1,从 268625 到 268626 填充到 short。 然后 268626 到 268628 short 不需要填充,全部与结构的最大类型对齐。

    来自同一个参考

    有一种方法可以最小化填充。程序员应该声明 结构成员按大小递增/递减顺序

    改进结构的方法是将char Data4; 直接放在char Data1; 之后 这样就不会浪费内存用于填充:

    struct MixedData
    {
        char Data1;
        char Data4;
        short Data2;
        int Data3;
    
    }md;
    
    printf("%p    %p    %p    %p", &md.Data1,&md.Data4, &md.Data2, &md.Data3);
    
    0x602270    0x602271    0x602272    0x602274
    

    基本假设,编译器在 x86 上坚持 int 的自然对齐

    【讨论】:

    • 为什么short前只使用2个字节而不是4个?
    • 但是如果我在你的回答中声明了两个连续的char,那么为什么不需要填充?
    • 在这种情况下,您的结构是对齐的,不需要填充。在您的情况下,填充是什么?在 Data1 之后添加一个字节以将 char 对齐到 short。 Data1 + Data4 = 2 char, 2 char = 2 bytes, short 两字节对齐,无需额外填充
    • int也需要4个字节,那么为什么在我的问题中short之后没有添加2个字节?
    • 因为您已经在 Data1 之后添加了一个字节的填充。 Data1 + 1 字节的填充 = 2 字节,在这 2 字节之后你有 2 字节的短 2+2 = 4 => 你与你的 int 对齐
    【解决方案2】:

    怎么样?

    1 字节字符 2 字节

    2 字节短 2 字节

    4 字节用于 4 字节 int

    ? 1 字节字符的字节数

    真正的问题是:为什么?

    这个问题的答案是here, structure padding and packinghere, sizeof != sum (fields)

    【讨论】:

    • 请告诉我代码中的空白填充是如何发生的?
    • 代码中的空白填充是什么意思?
    猜你喜欢
    • 2012-10-09
    • 1970-01-01
    • 2011-04-20
    • 2016-09-22
    • 2015-12-15
    • 1970-01-01
    • 2018-04-16
    • 2021-04-30
    • 2011-08-14
    相关资源
    最近更新 更多