内存对齐的目的是为了让CPU能一次获取到数据,从而提升性能 CPU只能使用基本类型,char, short, int, long, float, double 等,不能使用数组或结构体等复合类型(汇编中并没有一个指令能直接存取一个struct或数组)。所以:内存对齐的单位是基本类型,目标是让CPU能一次获取到基本类型的值。 分析内存对齐,只需要记住上一个小节中:变量地址的对齐是指变量地址 对 变量大小求模为0。 规则 - 如何计算
假设m为当前成员起始存储位置 n为其所需存储大小 需满足 m % n == 0
否则需从m+1位开始 直到满足条件
当结构体嵌套了结构体时,以数据成员的结构体的自身长度作为外部结构体的最大成员的内存大小,比如结构体a嵌套结构体b,b中有char、int、double等,则b的自身长度为8开始计算b结构体内子成员位置
最后结构体的内存大小必须是结构体中最大成员内存大小的整数倍,不足的需要补齐
struct Teacher{
char d;
int e;
short f;
int g;
}teacher;
struct tClass{
char a;
int b;
short c;
struct Teacher teacher1;
}class;
int main ()
{
printf ("%d\n",sizeof(class);
return 0;
}
chat a , int b , short c 如上面结构体一样计算到位置9 Class中最大成员为int 4字节 所以偏移到12号位置存储class中的chat d 剩下的类似普通结构体直到27号位置存储完共28位 28 可以整除最大成员大小 int 4字节 返回28
现代计算机中内存空间都是按照 byte 划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但是实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐。 3、内存对齐规则
每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。gcc中默认#pragma pack(4),可以通过预编译命令#pragma pack(n),n = 1,2,4,8,16来改变这一系数。
有效对其值:是给定值#pragma pack(n)和结构体中最长数据类型长度中较小的那个。有效对齐值也叫对齐单位。
了解了上面的概念后,我们现在可以来看看内存对齐需要遵循的规则:
(1) 结构体第一个成员的偏移量(offset)为0,以后每个成员相对于结构体首地址的 offset 都是该成员大小与有效对齐值中较小那个的整数倍,如有需要编译器会在成员之间加上填充字节。
(3) 结构体的总大小为 有效对齐值 的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。
#include<stdio.h>
struct
{
int i;
char c1;
char c2;
}x1;
struct{
char c1;
int i;
char c2;
}x2;
struct{
char c1;
char c2;
int i;
}x3;
int main()
{
printf("%d\n",sizeof(x1));
printf("%d\n",sizeof(x2));
printf("%d\n",sizeof(x3));
return 0;
}
|