您的位置:首页 > 其它

关于结构体字节对齐的问题

2016-01-14 10:24 344 查看
之前一直对字节对齐的问题不是很明白,今天花点时间记下来,先看一下例子:
struct st1 
{
   char a ;
   int  b ;
    short c ;
};

struct st2
{
  short c ;
   char  a ;
   int   b ;
};

结果是:

sizeof(st1) is 12

sizeof(st2) is 8 

1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。

2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.) 

3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐.

   那么对于s1来说, 第一个元素 char a,偏移地址offset为0,是本身字节大小1的整数倍,符合规则1; 第二个元素 int b, offset为1,本身自己大小为4,所以前面偏移要补3个字节这样新的offset=4才符合规则1,; 第三个元素的short c offset=8(1+3+4),本身字节大小为2 满足规则1;此时总共占用内存大小为
1+3+4+2=10个字节, 不符合规则3(不是int的整数倍),所以再补2字节。 结果就是12.

   同样对于s2来说, 第一个元素 short c,偏移地址offset为0,是本身字节大小2的整数倍,符合规则1; 第二个元素
char a, offset为2,本身自己大小为1,满足规则1; 第三个元素的int b, offset=3(1+2),本身大小为4,不符合规则1  ,所以前面偏移要补1个字节这样新的offset=4才符合规则1,;此时总共占用内存大小为
2+1+1+4=8个字节, 符合规则3(是int的整数倍) 结果就是8.

ps:Vc,Vs等编译器默认是#pragma pack(8),所以测试我们的规则会正常;注意gcc默认是#pragma pack(4),并且gcc只支持1,2,4对齐。套用三原则里计算的对齐值是不能大于#pragma
pack指定的n值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: