C语言中 struct 成员对齐

来源:互联网 发布:医疗软件注册流程 编辑:程序博客网 时间:2024/05/16 15:58
typedef struct A
{
int num1;
int num2;
double num3;

} A;


typedef struct B

{
int num1;
double num3;
int num2;

} B;

以上两个结构体 我们如果求其 sizeof(A) ,sizeof(B); 我想也不想给出的答案是 16 ,16 。

写个client  验证下 :



好吧,结果出来我很诧异,结构体的大小不是各成员之和吗?  


带着问题,百度下 原来这其中存在 结构体成员对齐的问题。

成员对齐规则如下:

1、 结构体的大小等于结构体内最大成员大小的整数倍
2、 结构体内的成员的首地址相对于结构体首地址的偏移量是其类型大小的整数倍,比如说double型成员相对于结构体的首地址的地址偏移量应该是8的倍数。
3、 为了满足规则1和2编译器会在结构体成员之后进行字节填充!


基于上面三个规则我们来看看为什么sizeof(B)等于24:首先假设结构体的首地址为0,第一个成员num1的首地址是0(满足规则2,前面无须字节填充,事实上结构体绝对不会在第一个数据成员前面进行字节填充),它的类型是int,因此它占用地址空间0——3。第二个成员num3是double类型,它占用8个字节,由于之前的num1只占用了4个字节,为了满足规则2,需要使用规则3在num1后面填充4个字节(4——7),使得num3的起始地址偏移量为8,因此num3占用的地址空间是:8——15。第三个成员num2是int型,其大小为4,由于num1和num3一共占用了16个字节,此时无须任何填充就能满足规则2。因此num2占用的地址空间是16——19。那么是不是结构体的总大小就是0——19共20个字节呢?请注意,别忘了规则1!由于结构体内最大成员是double占用8个字节,因此最后还需要在num2后面填充4个字节,使得结构体总体大小为24。

存在疑问:为什么结构体成员要对齐,这里可以参考资料,譬如 《高质量c++程序设计指南》。


根据 成员对齐规则,

struct C

{

  char c;

  int num;

};

 我们来推测下 sizeof(C) 的大小 

假使 结构体首地址是0,第一个成员c 首地址为0 (满足规则2 成员首地址的相对于结构地首地址的偏移量是char类型的整数倍),

第二个成员 num 如果首地址是1 ,那么不满足规则2,相对于机构体的首地址偏移量不是其类型的整数倍,所以在拿字节填充,

填充到3,那么num 的地址空间是4-7。此时结构体大小是8 ,满足规则1 ,结构体大小是最大成员大小的整数倍 ,刚好是4的 一倍。


0 0
原创粉丝点击