结构体内存字节对齐规律

2020-09-08  本文已影响0人  CrazySnow

结构体是由一批数据组合而成的一种新的数据类型。组成结构型数据的每个数据称为结构型数据的“成员”。
结构体指针的大小是8字节,结构体的大小是根据结构体成员的大小累积计算。

字节对齐的好处

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

字节对齐规则

基本数据类型的大小.png
struct Student {
        bool sex;    
//$\color{red}{1个字节}$  (0,1) 放在第0位,长度为1;起始位置是0
        short int age;
//  $\color{red}{2个字节}$ (2,2)放在第2位长度为2;起始位置是2
 //$\color{red}{*为什么没有放在第一位,起始位置必须是长度的整数倍,1不是2的整数倍}$
        void *address; 
// $\color{red}{8个字节}$(8,8)放在第8位,长度是8;起始位置是5,6,7,8;8是8的整数倍,所以起始位置是8
        float grade; 
// $\color{red}{4个字节}$(16,4)放在第16位,长度是4;起始位置是16;
        char  name[9];
// $\color{red}{9个字节}$(20,9)放在第29位,长度为9;起始位置是20;
// $\color{red}{*char是一个字节,虽然char  name[9]占9个位置,但是起始位置必须是长度(数据类型的长度)的倍数}$
};

结构体的大小是结构体中最大元素的整数倍,Student结构体中,char的长度是8,故Student结构体的大小为32

结构体内存计算图示.png
针对结构体嵌套的情况
struct Student2 {
  bool sex;
  short int age;
  void *address;
  float grade;
  char  name[9];
  Student1 stu;
};

结构体嵌套,最终的大小并不是Student2结构体内最大的元素的倍数,而是Student1Student2所有子元素里,最大的那一个的倍数,所以Student2的大小是8的倍数,按照上面的排列规则,得出结果是53,但是结果必须是8的倍数,故最终结果是56

字节重排

当我们在定义结构体时,如果数据成员的定义顺序安排的不合理就有可能会导致多余内存空间的占用和浪费。 为了达到最佳内存空间占用,系统在计算内存大小的时候,会对结构体内的元素进行重排,按照从小到大的原则重新排列,下图是Student1重排后的结果。

内存优化.png
上一篇下一篇

猜你喜欢

热点阅读