美文网首页
结构体内存字节对齐规律

结构体内存字节对齐规律

作者: CrazySnow | 来源:发表于2020-09-08 14:33 被阅读0次

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

字节对齐的好处

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

  • CPU的数据总线宽度决定了CPU对数据的吞吐量
  • 64位CPU一次处理64 bit也就是8个字节的数据,32同样,每次处理4个字节的数据

字节对齐规则

基本数据类型的大小.png
  • 数据成员对齐规则:struct 或者union的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如数据、结构体等)的整数倍开始
  • 数据成员为结构体:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储
    结构体的整体对齐规则:结构体的总大小,即sizeof的结果,必须是其内部做大成员的整数倍,不足的要补齐
    以下面结构体为例,计算Student结构体的大小:
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

相关文章

  • 第一天,内存对齐

    一对齐规则: 1.非结构体类型 32位 4字节对齐,64位 8字节对齐 2.结构体类型 以结构体中,最大内存的整数...

  • 结构体内存字节对齐规律

    结构体是由一批数据组合而成的一种新的数据类型。组成结构型数据的每个数据称为结构型数据的“成员”。结构体指针的大小是...

  • c语言结构体对齐

    1.什么是字节对齐 结构体里面一般会按照某种规则去进行字节对齐默认规则如下:对齐是按照结构体中长度最长的变量来对齐...

  • 结构体 字节对齐的练习

    结构体 字节对齐的练习 分析结构体大小struct S1 ...

  • #pragma pack(push,1)与#pragma pac

    这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式。 #...

  • fieldalignment 使用

    golangci-lint 会对结构体的内存字节对齐进行检查,会报下面的错误:fieldalignment: st...

  • #pragma pack&pop

    转这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式。 ...

  • iOS 技术

    结构体的字节对齐和OC对象的字节对齐? instance(实例对象)、class(类对象)、meta-class(...

  • 结构体

    1.结构体 2.结构体的内存对齐模式 编译器在编译一个结构的时候采用内存对齐模式,结构体总是以最大的成员最为对齐单...

  • ndk-基础知识

    数组和指针,数组指针,指针数组 结构体 内存对齐 内存对齐 结构体大小 S5DUD10BN083MHEJEX7TP...

网友评论

      本文标题:结构体内存字节对齐规律

      本文链接:https://www.haomeiwen.com/subject/vpldektx.html