内存对齐
让数据尽量按照一个寻址步长来存储,避免长存储,这叫内存对齐。
为什么要进行内存对齐,内存对齐是怎样的
先了解下地址线
地址线是用来传输地址信息用的。举个简单的例子:cpu在内存或硬盘里面寻找一个数据时,先通过地址线找到地址,然后再通过数据线将数据取出来。 如果有32根.就可以访问2^32B,也就是4GB,也就是说多一根地址线就是多了一个位,cpu是根据地址线来访问内存的,有多少根地址线就访问多少位的内存,每次访问都是如次,多了没用,多不起来,少了就造成浪费主频,以32位cpu和64位cpu为例:
CPU一次寻址的长度叫寻址步长,一次寻址步长长度为地址总线数(即一个指针占有的位),32位cpu就以四为寻址步长,64位cpu就以八为寻址步长,同理,n位cpu以n/8为寻址步长,
所以如果一个数据能存放在一个寻址步长内,那么一次访问就能获取这个数据的值,若是没有放在一个寻址步长内,那需要多次访问,并进行拼接才能获取数据。
ps:一个指针占的字节等于cpu位数除于一个字节的位数(8),然后因为要最大限度利用cpu的计算能力,所以指针保存的地址的最大值必是cpu计算2∧n(n是位数)的最大值(这既是地址最大值也是地址的个数或者说是所有可能,所以其中已经包含了数值为零的地址,那么2的n次方为最大值,而不是2的n次方减一),即cpu位数那么多的位的最大值。(这里地址都是指虚拟地址)
好处:
1.提高了寻址效率,能做到不遗漏字节,也不对某一字节重复寻址。
坏处
1.当一个数据不能填满一个寻址步长时,会留下空间,这些空间将被填充来达成内存对齐,就像棉花塞着,于是浪费了内存空间。
注意
1.内存对齐虽然和硬件有关,但是决定对齐方式的是编译器,编译时很多编译器会自动进行内存对齐,对于全局变量,GCC在 Debug 和 Release 模式下都会进行内存对齐,而VS只有在 Release 模式下才会进行对齐。而对于局部变量,GCC和VS都不会进行对齐,不管是Debug模式还是Release模式。。