C++内存对齐

什么是内存对齐?what
1
2
3
4
5
6
7
8
9
10
11
12
//32位系统
#include<stdio.h>
struct{
int x;
char y;
}s;

int main()
{
printf("%d\n",sizeof(s); // 输出8
return 0;
}

32位下,int4字节,char1字节,放到结构体中应该是5字节。但实际上是8字节。这就是内存对齐

为什么要内存对齐?why

尽管内存是以字节为单位,但是大部分处理器并不是按字节块来存取内存的.它一般会以双字节,四字节,8字节,16字节甚至32字节为单位来存取内存,我们将上述这些存取单位称为内存存取粒度

现在考虑4字节存取粒度的处理器取int类型变量(32位系统),该处理器只能从地址为4的倍数的内存开始读取数据。

假如没有内存对齐机制,数据可以任意存放,现在一个int变量存放在从地址1开始的联系四个字节地址中,该处理器去取数据时,要先从0地址开始读取第一个4字节块,剔除不想要的字节(0地址),然后从地址4开始读取下一个4字节块,同样剔除不要的数据(5,6,7地址),最后留下的两块数据合并放入寄存器.这需要做很多工作。

有了内存对齐,int类型数据只能存放在按照对齐规则的内存中,比如说0地址开始的内存。那么现在该处理器在取数据时一次性就能将数据读出来了,而且不需要做额外的操作,提高了效率。

内存对齐规则

每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。gcc中默认**#pragma pack(4)**,可以通过预编译命令#pragma pack(n),n = 1,2,4,8,16来改变这一系数。