参考【C/C++】内存对齐(超详细,看这一篇就够了)_c++内存对齐-CSDN博客
1)什么是内存对齐?
内存对齐是一种将数据在内存中的存储位置按照特定规则进行排列的方式。通常,数据会被存储在内存地址是其大小的整数倍的位置上。
例如,一个 4 字节的整数可能会被存储在内存地址是 4 的倍数的位置上。
2)为什么需要内存对齐?
简单来说,就是方便计算机去读写数据。
对齐的地址一般都是 n(n = 2、4、8)的倍数。
- 1 个字节的变量,例如 char 类型的变量,放在任意地址的位置上;
- 2 个字节的变量,例如 short 类型的变量,放在 2 的整数倍的地址上;
- 4 个字节的变量,例如 float、int 类型的变量,放在 4 的整数倍地址上;
- 8 个字节的变量,例如 long long、double 类型的变量,放在 8 的整数倍地址上;
一、提高内存访问效率
现代计算机体系结构中,内存访问通常是以特定大小的块为单位进行的。如果数据没有按照合适的对齐方式存储,可能会导致处理器需要进行多次内存访问才能获取完整的数据,从而降低内存访问效率。
例如,对于 32 位处理器,如果一个 4 字节的整数存储在内存地址不是 4 的倍数的位置上,处理器可能需要进行两次内存访问才能获取完整的整数。而如果整数存储在 4 的倍数的地址上,处理器可以一次性读取完整的整数,提高了访问效率。
二、满足硬件要求
某些硬件架构可能对数据的对齐有严格要求。如果数据没有正确对齐,可能会导致硬件错误或性能下降。
例如,一些特定的处理器指令可能只对特定对齐地址上的数据进行操作。如果数据没有按照要求对齐,这些指令可能无法正常执行。
三、提高数据结构的性能
对于结构体等复合数据类型,内存对齐可以提高其成员的访问效率。如果结构体的成员没有按照合适的对齐方式存储,访问结构体成员可能需要进行额外的内存访问和数据拼接操作,降低了性能。
例如,如果一个结构体包含一个整数和一个双精度浮点数,由于双精度浮点数通常需要 8 字节对齐,如果整数没有按照合适的方式对齐,访问双精度浮点数可能需要进行额外的内存访问。
基本变量类型所占大小:
数据类型 | ILP32(32位Linux系统) | LP64(大部分64位Linux系统) | LLP64(64位Windows系统) |
char | 1 字节 | 1 字节 | 1 字节 |
short | 2 字节 | 2 字节 | 2 字节 |
int | 4 字节 | 4 字节 | 4 字节 |
float | 4 字节 | 4 字节 | 4 字节 |
long | 4 字节 | 8 字节 | 4 字节 |
double | 8 字节 | 8 字节 | 8 字节 |
long long | 8 字节 | 8 字节 | 8 字节 |
指针 point | 4 字节 | 8 字节 | 8 字节 |
枚举 enum | 4 字节 | 4 字节 | 4 字节 |
结构体对齐的研究:
例1:
struct stu1 {char a[18];double b;char c;int d;short e;
};
//48字节
例2:
struct stu1 {char a[18];int b[3];short c;char d;int e;short f;
};
//44字节
例3:
struct stu1 {int a;char b[8];float c;short d;
};
//20字节
例4:
enum DAY {
MON = 1, TUE, WED, THU, FRI, SAT, SUN
};
struct stu1 {char a[5];char b[3];enum DAY day;int *c;short d;int e;
};
//(32位)24字节 (64位)32字节
32位:
64位: