二、涉及位域的内存对齐
注:由于能力有限,在此仅讨论在VC++6.0编译环境下的情况,对于其他编译环境下的情况,由于没有硬件支持,只能作罢,但会将查到的相关知识贴在最后,但不做讨论。
涉及位域的内存对齐规则(规则太枯燥,如果不想看就看例子啦,呵呵) 如下,后用代码分析验证:
1) 若相邻成员变量类型相同,且其位宽之和不大于成员变量类型位宽(在此严重强调,是 类型位宽 而不是成员变量sizeof,也不是类型的sizeof或者其他什么)大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同,但其位宽之和不大于成员变量的类型宽度大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,不同位域字段存放在不同的位域类型字节中;(这一条其实会根据编译器的不同而采用不同的规则,此处以VC++6.0标准来说明)
4)其实不存在4),这一条是说,在此,还要遵守不涉及位域的2),3)条规则,也部分遵守不涉及位域的第一条规则
实例分析,代码如下:
10};
11int main ()
12{
13
14
15
16
17}
将一步一步来分析内存情况:
1、从起始地址(假设为零)为c1分配空间,如下图:
2、接下来,为c2分配空间,由于c1和c2的类型都为char,且c1和c2的位宽之和为8不大于类型char的位宽8,根据规则1,c2的空间分配如下:
3、接下来,为s1分配空间,此时,有一个问题,s1的内存空间的起始地址是从哪儿开始呢?1还是2?根据上一节介绍的我们可知,s1的对齐模数为2,此处上一节的规则规则依然适用,结合这里的第三条,1处,填充CC,从2处开始分配:
4、接下来,为s2分配空间,重复第二步,非配如下(此处也要注意一下的,因为一个s2的空间非配跨越了两个字节,而且都不是完整的占有一个字节):
5、接下来为i分配内存空间便如同上一节讲的一样了,如下图:
7、最终的运行结果,也与分析一致:
呵呵,如果上边的你都看懂了,何不做做下边的这个小练习呢?看看你能做对不~
代码
2 using namespace std;
3 struct A
4 {
5
6
7
8
9 };
10 int main ()
11 {
12
13
14
15
16
17
18
19 }
原文来自:雨枫技术教程网 http://www.fengfly.com
原文网址:http://www.fengfly.com/plus/view-173130-1.html