内存对齐
什么是内存对齐?
内存对齐:在计算机中,内存空间按照字节划分,理论上可以从任何起始地址访问任何类型的变量。但实际上在访问特定类型的变量的时候需要从特定的地址开始,这就需要各种类型的数据按照一定的规则在空间上排列,而不是顺序的一个接一个的存放,这就是内存对齐,也叫字节对齐。
为什么要内存对齐?
内存对齐的作用:
- 可移植性:因为不同平台对数据的在内存中的访问规则不同,不是所有的硬件都可以访问任意地址上的数据,某些硬件平台只能在特定的地址开始访问数据。所以需要内存对齐。
- 性能原因:一般使用内存对齐可以提高CPU访问内存的效率。如32位的intel处理器通过总线访问内存数据,每个总线周期从偶地址开始访问32位的内存数据,内存数据以字节为单位存放。如果32位的数据没有存放在4字节整除的内存地址处,那么处理器需要两个总线周期对数据进行访问,显然效率下降很多;另外合理的利用字节对齐可以有效的节省存储空间。
默认内存对齐影响因素:与平台架构(位数)和编译器的默认设置有关。
结构体数据对齐
C++标准规定,int占一个机器字长。在32位系统中int占32位,也就是4个字节,而在老式的16位系统中,int占16位,即2个字节。而C++标准中只限制规定short int不能超过int的长度,具体长度的可以由C++编译器的实现厂商自行决定。目前流行的32位C++编译器中,通常int占4字节,short int占2字节。其中short int可以简写为short。
结构体如何处理数据对齐?
- 每种类型的成员变量的起始地址需要是自身大小的整数倍,如果不是,前面的变量就需要填充;
- 结构体自身的大小还需要是最大成员size的整数倍;
( G C C GCC GCC编译器默认的最大对齐模数为4,超过四字节时仍按照4字节对齐。 a r m − l i n u x − g c c arm-linux-gcc arm−linux−gcc默认最大对齐字节数为8字节)
比如有如下一个结构体:
struct stu{char sex;int length;char name[10];};struct stu my_stu;
sex后面填充3个字节使得length字节对齐,name后面填充2个字节,使得结构体整体对齐。(最大成员size是4字节,所以结构体整体按照4字节的整数倍对齐),于是我们sizeof(my_stu)会得到长度为20,而不是15.
struct student