为什么要对齐内存?
平台(移植)原因:访问任意地址上的任意数据并不是所有硬件平台都能做到的。一些平台只能在某些地址处取特定类型的数据.
性能(硬件)原因:经过内存对齐之后,CPU对内存的访问速度就是大大提升。(访问未对齐的内存,CPU需要执行两次访问操作。而经过对齐之后的内存仅需要一次访问。)
总结:内存对齐本质上就是通过牺牲空间来换取时间的做法。
内存分配规则:
1)第一个成员在与结构体变量偏移量为0的地址处。
2)从第二个成员开始,每个成员都要对齐它自身对齐数的整数倍地址。(每个成员的对齐数是自身的大小和默认对齐数的较小值,VS平台的默认对齐数是8,linux下是4。)
3)结构体的总大小是整体中最大成员类型的整数倍。
如何修改默认对齐数?
pragram pack(4); //把默认对齐数修改为4。
pragram pack(); //恢复环境默认对齐数。
Windows下VS平台默认对齐数可修改为(1,2,4,8)。
Linux环境下可修改为(1,2,4)。
1.结构体:
1.1 示例
struct Stu //结构体的类型为struct Stu,相当于int/float,struct后边的Stu不能丢 { int age=100000; char name="CrankyPants"; }student1;
结构体在赋值的时候和数组很类似,但是有一点区别就是结构体如果在初始化的时候没有赋值,那么后期赋值就只能逐个元素进行赋值。
2、位断:
2.1 示例
struct AAA { int a:2; //”:“后边的2,表示位域的长度 int b:6; int c:4; int d:2; }data;
2.2
一个位域只能存在于一个字节之中,当一个字节中剩下的空间不足以存放另一个位域的时候,应从下一个单元起储存该位域。但是当有意要从下一个单元开始存储的时候,就可以通过创建一个空位域的方法来实现。比如:
示例
struct BBB { int a:2; int :0; int b:6; int c:4; int d:2; }deta2; // 此时位域所占空间为3个字节,相比上个位域多了一个字节。
2.3
因为位域不能跨字节存储,所以在定义位域的长度时不能超过平台中的默认对齐数。
(VS环境下的默认对齐数是8,linux环境下是默认对齐数是4。)
3、枚举:
3.1 示例
enum Day { Mon; Tues; Wed; Thur; Fri; Sat; Sun; };
3.2 枚举的应用
枚举类型常量常用于循环变量控制,枚举常量则用于多路选择控制情况。4、联合体:
4.1 示例
union Data { int i=0; char ch="A"; float f=0.12; }data;
4.2 特点
联合体中成员公用同一块内存,存在内存对齐,最后一次赋值有效。联合体的大小至少为最大元素的大小,但不一定是,联合大小是最大对齐数的最小整数倍。