填充如何在C编译器中工作

时间:2014-08-13 19:01:35

标签: c memory struct alignment padding

我试图了解填充如何在32位编译器中工作。我把它归结为以下示例代码:

#include <stdio.h>

#define uchar unsigned char
#define ushort unsigned short

typedef struct  {                               
    ushort  a;
    ushort  b[60];
} INNER;

typedef struct{
    uchar z;
    INNER x;

}OUTER;

int main(void) {

    printf("%d\n",sizeof(INNER));
    printf("%d",sizeof(OUTER));
    return 0;
}

该程序的输出是:

122 /*actual*/
124 /*actual*/

我的期望是

124 /*expectation*/
126 /*expectation */

现在,据我所知,如果有任何必要的填充,它应该在INNER结构中。即INNER结构应填写如下:

typedef struct  {                               
    ushort  a;
    ushort  b[60];
    ushort compiler_pad; /* I believe compiler should have done this */
} 

但相反,我认为编译器正在执行以下操作:

typedef struct{
    uchar z;
    INNER x;
    uchar compiler_pad; /* I believe compiler is doing this */
}OUTER;

有谁知道为什么父结构被填充,而不是纠正内部结构的对齐?

其他细节: - sizeof(uchar)是1 - sizeof(ushort)是2 - 我在32位处理器上,对齐是4 - 我已经检查了this问题

1 个答案:

答案 0 :(得分:3)

INNER连续有61个ushort个标量,完全符合122个字节; 当自己分配时,它不需要任何填充。这就是INNER内没有填充的原因。

但是,

OUTER包含一个uchar(根据定义,的大小为1 ),然后是61 ushort个。 ushort的硬件对齐要求是2,而不是1,因此编译器必须在uchar和61 ushort之间插入一个填充字节,即之前的 > INNER对象,以满足它们的对齐要求。如您所料,INNER end 的填充不会安排INNEROUTER内正确对齐。

编辑:编译器在 zx之间插入填充而不是 OUTER

typedef struct {
    uchar z;
    uchar compiler_pad;
    INNER x;
} OUTER;

您可以在程序顶部添加#include <stddef.h>,然后打印offsetof(OUTER, x),以便自行确认。打印的数字为2。