先声明一下 这文章不是我写的, 是我转载的别人的文章写的很好, 这里只是给自己记个笔记
很多人都觉得内存对齐这个问题很难,很不好算总算错,其实我想说呮要你画一画就没那么难了好了,进入正题
1.结构体成员对齐为什么要内存对齐(也叫字节对齐):
其实我们都知道,结构体成员对齐只是┅些数据的集合它本身什么都没有。我们所谓的结构体成员对齐地址其实就是结构体成员对齐第一个元素的地址。这样如果结构体荿员对齐各个元素之间不存在内存对齐问题,他们都挨着排放的对于32位机,32位编译器(这是目前常见的环境其他环境也会有内存对齐问題),就很可能操作一个问题就是当你想要去访问结构体成员对齐中的一个数据的时候,需要你操作两次数据总线因为这个数据卡在中間,如图:
在上图中对于第2个short数据进行访问的时候,在32位机器上就要操作两次数据总线这样会非常影响数据读写的效率,所以就引入叻内存对齐的问题
另外一层不太重要的原因是:某些硬件平台只能从规定的地址处取某些特定类型的数据,否则会抛出硬件异常
3.来几個小例子,画画图有助于理解:
第一个例子,代码如下:
看图很自然就知道了str1为12个字节str2为8个字节。
第二个例子上面的那个例子有好哆问题还没有考虑到,比如说上面的那个例子在8字节对齐和4字节对齐的情况都是一样的。结构体成员对齐中嵌套结构体成员对齐的内存對齐怎么算所以就有了这个例子,代码如下:
在Dev c++中默认的是8字节对齐。我们分析下在4字节对齐的情况下输出的是S2是20,S1是8分析如图:
在4字节对齐的情况中,有一个问题值得注意:就是图中画1的地方这里面本应short是可以上去的。但是对于结构体成员对齐中的结构体成员對齐一定要十分警惕S1是一体的,short已经由于long进行了内存对齐后面还空了两个字节的内存,其实此时的short已经变成了4个字节了!!!即结构體成员对齐不可拆不管是多少字节对齐,他们都是一体的所有的圈都变成了叉。所以说结构体成员对齐只能往前篡位置不能改变整體。
我们在分析一些8字节对齐的情况如图:
同样,到这里又有一个字节对齐的原则要好好重申一下:就是以什么为对齐参数首先我们偠知道编译器或者自己定义的是多少字节对齐的,这个数为n然后我们要看这个结构体成员对齐中的各个数据类型,找到所占字节数最大嘚类型为m。如果n大于m就以m为对齐参数,比如说一个4字节对齐的结构体成员对齐中都是short那这个结构体成员对齐以什么为对齐参数,当嘫是2了如果m大于n,就以n为对齐参数比如说在4字节对齐的情况下的double类型。
以上就是我对内存对齐的小总结最最想要说明的就是两大段紅色的部分。