c/c++中关于struct内存对齐问题

719 views

题:

struct st1{                                       struct st2{
          int i;                                                 char c;
          char c;                                             int i;
          short s;                                            short s;
       };                                                   };

上述两结构体在内存中占用字节是多少,即sizeof(struct st1)=?, sizeof(struct st2)=?
解:8, 12

思考:这是struct结构的内存对齐问题,结构体的内存布局依赖于CPU、操作系统、编译器及编译时的对齐选项。其主要有:

1)结构体内部成员对齐
对于结构体内部成员,通常会有这样的规定:各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。但是也可以看到,有时候某些字段如果严格按照大小紧密排列,根本无法达到这样的目的,因此有时候必须进行padding。各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调 整位置,空缺的字节编译器会自动填充也就是padding。如下图所示:

662029145240471388

图中st1,第一个为int型,占用4个字节,第二个为char型,其偏移量为4,char所占的字节数为1,则偏移量是其占用字节数的倍数,则仅列其后,第三个为short型,占用字节数为2,前面已有字节为5,不是2的倍数,所以char后面padding一个字节,使得short的其实地址为6,所以对齐后,共占用8个字节。同理可得str2占用12个字节

2)结构体之间对齐(此并不是考虑结构体内部的对齐,而是一组结构体的对齐,在计算单个结构体占用字节时并不考虑)

考虑整个结构体的对齐需求。ANSI C标准规定结构体类型的对齐要求不能比它所有字段中要求最严格的那个宽松,可以更严格。实际上要求结构体至少是其中的那个最大的元素大小的整数倍。因为有时候我们使用的是结构体数组,所以结构体的大小还得保证结构体数组中各个结构体满足对齐要求,同时独立的结构体与结构体数组中单个结构体的大小应当是一致的。


每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数32位机上是8)。程序员可以通过预编
译命令#pragma pack(n),n=1,2,4,8,16 来改变这一系数,其中的n 就是你要指定的“对齐系数”。

指定对齐:
一般的,可以通过下面的方法来改变缺省的对齐条件:
使用伪指令#pragma pack(n),编译器将按照n个字节对齐;
使用伪指令#pragma pack(),取消自定义的字节对齐方式;
注意:如果#pragma pack(n)中指定的n大于结构体中最大的成员的size,则其不起作用,结构体仍然按照size最大的成员进行对齐。

发表评论

电子邮件地址不会被公开。 必填项已用*标注