找工作笔试面试补充知识(1)---内存对齐
前言:
之前分析迅雷近几年笔试题的时候,提到了一类问题考察的是内存对齐的知识。之前做的总结中少了这部分知识,而回忆起来,去年的大大小小那么多场笔试,确实有不少公司都还考察这个,这里正好就单独写一篇,总结总结这个问题吧。有不当之处,欢迎大家留言指正,谢谢!
一.何为内存对齐,内存对齐的作用我们现在使用的算机中内存空间都是按照字节(Byte)划分的,理论上说,似乎对任何类型的变量的访问可以从任意地址开始,但实际情况则是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型的数据按照一定的规则在内存空间上排列,而不是顺序的一个接一个地排放,这就是对齐。
二.编译器内存字节对齐的原则1. 数据类型的自身对齐值
数据类型的自身对齐值:其在内存中所占的字节数,如在32位系统中,char为1字节,short为2字节,int、float、double、long为4字节。
2. 结构体或类的自身对齐值结构体或类的自身对齐值:其成员中自身对齐值最大的那个值。
3. 默认对齐值结构体或类的默认对齐值为其成员中自身对齐值最大的那个值。
4. 指定对齐值使用#pragma pack(value)时指定的值value。
5. 结构体和类的有效对齐值结构体和类的有效对齐值为:没有指定对齐值时为默认对齐值和自身对齐值的最小值;当指定了对齐值后为指定对齐值和自身对齐值的最小值。
在编码时,我们可以这样动态修改编译器的对齐值:
1)修改默认对齐值,指定新的内存对齐值:#pragma pack(value)
2)取消指定的内存对齐值,恢复默认对齐值:#pragma pack()
对于一个结构体,不但需要对其每个成员变量进行内存地址对齐,还要对结构体本身进行对齐。具体规则是:在假设结构体起始地址为0x0000的情况下,要求各成员变量的起始地址必须是其相应有效对齐值的整数倍,并要求结构体的大小也为该结构体有效对齐值的整数倍。
例4.1:
#pargma pack(8)struct A{ short a; //有效对齐值为min(2,8) = 2 long b; //有效对齐值为min(4,8) = 4;}; struct B{ char c; //有效对齐值为min(1,8) = 1 struct B s; //有效对齐值为min(4,8) = 4 short e; //有效对齐值为min(2,8) = 2};#pargma pack()分别求出sizeof(struct A)和sizeof(struct B)的值。
类似例4.1可分析:
sizeof(struct A)= 8,sizeof(struct B)= 16