前置知识
CPU通过地址总线向内存寻址,若地址总线为8,则最多只能寻址256 byte的内存空间,地址总线为32,则最多能寻址4 GB的内存空间。内存通过数据总线将数据传回CPU进行处理,数据总线能处理的数据长度,称为机器字长。
为什么需要内存对齐
是CPU取数过程中一种策略,该策略通过以空间换时间,提高CPU的效率。
- 平台移植:有些CPU可以访问任意地址上的数据(该CPU也是做了很多的处理),而有些CPU只能在特定地址访问数据,因此不同的硬件平台具有差异性,这样代码不具备移植性。如果在编译时候,将分配的内存对齐,这样代码就可以在不同的平台移植。
- 提升性能:CPU访问内存时候,是以字长为单位访问的。如果一个占8位字节的数不对齐,像下面的内存排列:
假设机器字长为8位,则CPU就要进行两次取数,第一次先取出0 ~ 7字节的,第二次取出8 ~ 15字节的,然后对这两次取数进行合并。这一顿操作会影响效率。
内存对齐的具体做法
- 综上所述,编译器会将不同的类型数据,放到不同的内存起始位置上,就是内存对齐。
- 内存对齐是指首地址对齐。每个变量的起始地址都要是该成员字节数的整数倍。
结构体的内存对齐
结构体的内存对齐遵循以下原则:
- 每个成员的起始地址都要是该成员字节数的整数倍,也就是起始地址 % sizeof(变量) = 0
- 整个结构体的起始地址,是该结构体成员中最大成员的整数倍。
示例
在32位机器上,有以下结构体:
示例一
typedef struct{
char a;
double b;
char c;
}test1;
则该结构体在内存中的排列如下所示:
该结构体成员的内存对齐,使得该结构体的大小为24个字节
示例二
typedef struct{
char a;
char c;
double b;
}test1;
该结构体在内存中的排列如下所示:
因此该结构体的大小为16个字节
结构体对齐对于开发的启示
写结构体成员的时候,将占字节数少成员变量写在前面,这样将减少整个结构体内存的占用