已知对齐系数和未知对齐系数结构体如何内存对齐

一.内存对齐:

许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址是某个数k(通常要求为4或8的倍数),这就是所谓的内存对齐。

二.内存对齐优点:

1.平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

2.性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。


已知对齐系数内存对齐

struct或者union成员对齐规则:

第一个数据成员放在offset为0的地方,对齐按照对齐系数自身所占用的字节数中,两者比较小的那个进行对齐。
struct或者union的整体对齐规则:
在struct或者union数据成员完成各自对齐之后,struct或者union本身也要对齐,对齐按照对齐系数和struct或者union中最大数据成员长度中,比较小的那个进行。先局部成员对齐,然后再全局对齐。

例:

对齐系数为8

1.struct A

{

  char  a;

   int   b;

};

已知对齐系数和未知对齐系数结构体如何内存对齐

共8字节,a(1字节)占据0号单元格,b(4字节)与对齐系数取小为4,它的偏移地址必须是4的倍数,最近的4的倍数是4,所以b从4开始占4~7这4个单元格,前面的1~3三个单元格对齐。

2.对齐系数为8

struct B

{

char a;

short b;

int c;

};

已知对齐系数和未知对齐系数结构体如何内存对齐

共8字节,a(1字节)占据0号单元格,b(2字节)与对齐系数取小为2,它的偏移地址必须为2的倍数,最近的2的倍数为2,所以b占据2~3这两个单元格,c(4字节)与对齐系数取小为4,它的偏移地址必须为4的倍数,最近的4的倍数为4,所以c占据4~7这四个单元格。

3.对齐系数为8

struct C

{

char a;

int b;

int c;

double d;

};

已知对齐系数和未知对齐系数结构体如何内存对齐

共24字节,a(1字节)占据0号单元格,b(4字节)与对齐系数取小为4,它的偏移地址必须为4的倍数,最近的4的倍数为4,所以b占据4~7这两个单元格,c(4字节)与对齐系数取小为4,它的偏移地址必须为4的倍数,最近的4的倍数为4,所以c占据8~11这四个单元格,d(8字节)与对齐系数取小为8,所以d占据16~23这八个单元格。

如果在不知道当前编译器的对齐系数如何内存对齐:

结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始

在struct或者union数据成员完成各自对齐之后,struct或者union本身也要对齐,对齐按照struct或者union中(基本数据类型)最大数据成员长度中,最大的整数倍计算。

例:

1.struct D

{

 char a;

  int   b;

short c;

};

已知对齐系数和未知对齐系数结构体如何内存对齐

共12字节,a(1字节)占据0号单元格,b(4字节)最近整除四的位置为4,所以b从4~7占据四个单元格,c(2字节)最近整除2的倍数为8,所以c占据8~9这两个单元格,但结构体之间也要进行对齐,最近整除四的位置为12,所以struct D占据0~11这11个单元格。

2.区分:

struct E                                                     

{                                                           

int a;                                                           

struct EE                                                      

{                                                             

char b;

int c;

}EE;

};

共12个字节,a(4字节)占据0~3这四个单元格,b(1字节)最近整除1的位置为4,所以b占据4号单元格,c(4字节)最近整除4的位置为8,所以c占据8~11这四个单元格。

 struct F

 {

 int a;

double b;

 };

已知对齐系数和未知对齐系数结构体如何内存对齐

共16个字节,a(4字节)占据0~3这四个单元格,b(8字节)最近整除8的位置为8,所以b占据8~15这八个单元格。