校招面试常见问题,文体部面试常见问题
终极管理员 知识笔记 43阅读
还是用一个例子带出这个问题看下面的小程序理论上32位系统下int占4bytechar占一个byte那么将它们放到一个结构体中应该占415byte但是实际上通过运行程序得到的结果是8 byte这就是内存对齐所导致的。
//32位系统#include<stdio.h>struct{ int x; char y;}s;int main(){ printf(%d\n,sizeof(s); // 输出8 return 0;}
现代计算机中内存空间都是按照 byte 划分的从理论上讲似乎对任何类型的变量的访问可以从任何地址开始但是实际的计算机系统对基本类型数据在内存中存放的位置有限制它们会要求这些数据的首地址的值是某个数k通常它为4或8的倍数这就是所谓的内存对齐。

那么接下来我们来说一下结构体中内存对齐的规则:
1.对于结构体中的各个成员第一个成员位于偏移为 0 的位置以后的每个数据成员的偏移量必须是min(#pragma pack()制定的数数据成员本身长度)的倍数。 n 1,2,4,8,16
每个特定平台上的编译器都有自己的默认“对齐系数”也叫对齐模数。gcc中默认#pragma pack(4)可以通过预编译命令#pragma pack(n)n 1,2,4,8,16来改变这一系数。

2.在所有的数据成员完成各自对齐之后结构体或联合体本身也要进行对齐整体长度是 min(#pragma pack())制定的数长度最长的数据成员的长度)的倍数
二、为什么内存对齐内存对齐的作用
1.经过内存对齐之后CPU 的内存访问速度大大提升。因为 CPU 把内存当成是一块一块的块的大小可以是24816 个字节因此 CPU 在读取内存的时候是一块一块进行读取的块的大小称为内存读取粒度。比如说CPU 要读取一个 4 个字节的数据到寄存器中(假设内存读取粒度是 4)如果数据是从0字节开始的那么直接将0-3 四个字节完全读取到寄存器中进行处理即可。
2.如果数据是从1字节开始的就首先要将前 4 个字节读取到寄存器并再次读取 4-7 个字节数据进入寄存器接着把0字节567字节的数据剔除最后合并 1234 字节的数据进入寄存器所以说当内存没有对齐时寄存器进行了很多额外的操作大大降低了 CPU 的性能。 3.另外还有一个就是有的 CPU 遇到未进行内存对齐的处理直接拒绝处理不是所有的硬件平台都能访问任意地址上的任意数据某些硬件平台只能在某些地址处取某些特定类型的数据否则抛出硬件异常。所以还有利于平台移植。