C语言结构中的边界对齐问题

来源:互联网 发布:类似卓讯云客宝软件 编辑:程序博客网 时间:2024/05/16 11:31
没错,今天2月14,单身狗如我情人节也只能苦逼地撸代码了。不知道大家有没有发现一个奇怪的现象,见图~

test的长度是8!!!
结构test里面包含了1个int型变量和2个char型变量,照理说sizeof( struct test )应该等于它们三个相加的结果6才对,为什么会等于8呢?
事实上,结构成员在内存中的存储并不是想当然地一个紧挨着一个排列下来的,由于提高数据读取速度的要求以及其他一些方面的原因,计算机系统对内存中基本数据类型的存放存在一种内存对齐机制,即要求这些数据的首地址必须是某个数K(通常为4或8)的整数倍,具体规则如下:
1.编译器按照结构体成员列表顺序给每个成员分配内存
2.当成员需要满足正确的边界对齐时,成员之间用额外字节填充
3.结构体的首地址必须满足结构体中边界对齐要求最为严格的数据类型所要求的首地址
4.结构体的大小为其最宽数据类型的整数倍

知道了这些规则,这个现象就不难理解了,如下图,int类型的a大小为4字节,占据图中1,2,3,4这四个字节,char型的b,c长为1字节,分别占据5,6两个字节位置,为满足规则4,第7,8两位被填充进来作为结构体的一部分,因而这个结构体的长度是8个字节。这里写图片描述

现在再来看看下面这种情况!
这里写图片描述

int型的a被放在了结构体成员列表的第2位,此时结构体的长度变成了12,按上面的规则,a,b,c在内存中的排列是下面这种情况:
这里写图片描述
b是成员列表第1位所以先存储占一个字节的b,为满足对齐规则,第2,3,4位用于填充,第5,6,7,8位用来存储int型的a,第9位存储c,为满足规则四,10,11,12位用于填充。(这里说明一下,计算机内存中地址是从0开始的,也就是说上图中的1,2,3…12实际上应该是0,1,2…11,画图时没注意。。。)

C语言stddef.h头文件中定义了一个宏offsetof,可用于得到结构体成员存储位置相对于结构体首地址的偏移量,可以用来验证上面的解释,其原型为:offsetof(type,member),下面我们就来验证一下~
这里写图片描述
结果显示a相对于结构体起始位置的偏移量是4个字节,符合上面的分析~

下面给大家分享一道我今天碰到的某大公司笔试题~
这里写图片描述
正确答案是C~~~

1 0