什么是内存对齐?
为了提高程序的性能,数据结构应该尽可能地在自然边界上对齐。
为什么要内存对齐?
1、便于移植:不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、提高处理器访问速度:对于未对齐的内存,处理器可能需要访问两次内存才能将数据完全读出,而对于对齐的内存,处理器只需要一次即可。
下面先举几个例子看一下
struct st_girl
{
double d; //8
char c; //1
int i; //4
};
运行结果:sizeof(struct st_girl) is 16
struct st_girl
{
char d;
char c;
int i;
};
运行结果:sizeof(struct st_girl) is 8
struct st_girl
{
char d;
int c;
char i;
};
运行结果:sizeof(struct st_girl) is 12
为什么会出现这种现象呢?特别是第二个例子,明明结构体的成员一样,只是顺序不同,但是所占内存却不一样,这就是内存对齐导致的。
这里我们使用的是VS2019 64位,默认对齐数是8,
结构体大小计算
例1
所以该结构体的大小为24字节
例2
所以该结构体的大小为16字节
修改默认对齐数
要修改编译器的默认对齐数,我们需要借助于以下预处理命令:
#pragma pack()
如果在该预处理命令的括号内填上数字,那么默认对齐数将会被改为对应数字;如果只使用该预处理命令,不在括号内填写数字,那么会恢复为编译器默认的对齐数。
知识卡片:Linux的gcc没有默认内存对齐数
struct st_girl
{
char d; //1
long double c; //16
char i; //1
};
结构体大小:48字节
#pragma pack(8)
struct st_girl
{
char d; //1
long double c; //16
char i; //1
};
结构体大小:32字节
于是,当结构体的对齐方式不合适的时候,我们可以自己更改默认对齐数