C中的内存对齐

时间:2012-11-26 05:01:03

标签: c memory alignment

这是一个片段:

#pragma pack(4)
struct s1
{
    char a;
    long b;
};
#pragma pack()

#pragma pack(2)
struct s2
{
    char c;
    struct s1 st1;
};
#pragma pack()


#pragma pack(2)
struct s3
{
    char a;
    long b;
};
#pragma pack()

#pragma pack(4)
struct s4
{
    char c;
    struct s3 st3;
};
#pragma pack()

我虽然sizeof(s4)应该是10或12.但它结果是8。 我使用的是Visual C ++ 6.0。有人可以告诉我为什么吗?

4 个答案:

答案 0 :(得分:2)

#pragma pack(2)
struct s3
{
    char a;
    long b;
};
#pragma pack()

因此s3的打包对齐为2,其大小为1(对齐1)+ 1(填充)+ 4(对齐2)= 6.

#pragma pack(4)
struct s4
{
    char c;
    struct s3 st3;
};
#pragma pack()

s4的打包对齐为4,其大小为1(对齐1)+ 1(填充)+ 6(对齐2)= 8.

请注意,#pragma pack不会对更宽松的对齐要求进行“额外对齐”。它只会减少对齐,即控制“打包”对齐。

答案 1 :(得分:1)

The documentation for #pragma pack(n)说“成员的对齐将在一个边界上,该边界是n的倍数或成员大小的倍数,以较小者为准”。但我认为这是不正确的;文档应该说成员的对齐方式将在n的倍数或成员的对齐要求的边界上,以较小者为准。

struct s3的对齐要求为2(由于声明时#pragma pack(2)有效)。因此,即使在有效#pragma pack(4)的结构中,它仍然会得到2的对齐。所以struct s4的布局如下:

 char c;
 char padding;      // for alignment of the `struct s3`
 char s3.a;
 char s3.padding;   // for alignment
 long s3.b;

总大小== 8.

答案 2 :(得分:0)

s3char(1)+ long(4)= 5 - > 6(打包)

s4中,char(1)+ struct s3(6)= 7 - > 8(打包)

我实际上并不确定#pragma pack是如何运作的,但这似乎是合理的。

答案 3 :(得分:0)

这证实了迈克尔伯尔所说的话:

#include <stdio.h>

#pragma pack(push, 2)
struct s3
{
    long b;
};
#pragma pack(pop)

struct s4
{
    char c;
    struct s3 st3;
};

int main() {
    printf("%lu, %lu\n", sizeof(s3), sizeof(s4));
    return 0;
}

输出:4,6