一,什么是内存对齐?
现代计算机中的内存空间都是按字节划分的,理论上似乎我们对任何类型变量的访问都可以在任意地址处进行,但实际上计算机中对基本数据类型的内存中的位置是有限制的,要求其首地址按照某一个数及其倍数进行对齐。
有如下例子:
4+1=5,本来A的大小应该为5字节,但有了内存对齐后就成了8字节。
二,为什么要有内存对齐?
-
我们的内存是以字节为单位的,但是我们的处理器在读取内存时,却不是以字节为单位的,其一般以内存块进行读取,可能为4,8,16… 。
那么假如没有内存对齐,我们读取int类型的变量,先读取前四个字节,若没有将完整的int读完,那么就需要将这四个字节中的不需要的进行剔除,然后再读4字节,再进行筛选剔除,最后将这两块进行合并后,才能形成我们所需要的一个完整的4字节int整型所需的数据。
要是有了内存对齐(以4为对齐数),我们就能保证这个int类型的数据一次就能读出来。提高了效率。 -
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常
三,内存对齐规则?
每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。gcc中默认#pragma
pack(4),可以通过预编译命令#pragma pack(n),n = 1,2,4,8,16来改变这一系数。
- 第一个成员在与结构体变量偏移量为0的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的值为8,g++中默认为4
- 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍.