结构体内存对齐

作者:牛客223996号
链接:https://www.nowcoder.com/exam/test/73333051/submission?examPageSource=Intelligent&pid=52556170&testCallback=https%3A%2F%2Fwww.nowcoder.com%2Fexam%2Fintelligent%3FquestionJobId%3D10%26tagId%3D21003&testclass=%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91
来源:牛客网

类型长度
  • 32位操作系统:
    char : 1 int :4 short : 2 unsigned int : 4 long : 4
    unsigned long : 4 long long : 8 float : 4 double : 8 指针: 4
  • 64位操作系统
    char : 1 int :4 short : 2 unsigned int : 4 long : 8
    unsigned long : 8 long long : 8 float : 4 double : 8 指针: 8
结构体所占用的内存与其成员在结构体中的声明顺序有关,对齐规则:
  • 每个成员分别按自己的对齐字节数(指它的类型而不是总长度,如double aa和char bb[9],应该是按照8对齐) 和 PPB(指定的对齐字节数,32位机默认为4,64位机为8)两个字节数最小的那个对齐。对齐 指成员它所在的存储位置是 两个字节数最小 的整数倍!!

  • 复杂类型(如结构体)的默认对齐方式是它最长的成员的对齐方式。

  • 结构体对齐后的长度必须是成员中最大的对齐参数~~(PPB)~~ 的整数倍。如32位系统中如果有double,最后总长度也是8的整数倍!

  • 结构体作为数据成员的对齐规则:在一个struct中包含另一个struct,内部struct应该以它的最大数据成员大小(指它的类型而不是总长度)的整数倍开始存储。

  • 结构体里面的如果成员为 指向结构体的指针,所占空间为当前系统下指针所占空间。

  • ps:只是成员之间的内存被浪费,并不是有成员多占用了内存。不够就补空字节。

    举例1: 在64位操作系统中的大小。
      struct t{ 
          long a; 
          short b; 
          int c; 
          int *d;  
          char e; 
      } 
    

    分析:
    按照声明的顺序一个一个分配内存空间。

    首先 long 型变量a,在64位地址空间中,long型占8个字节,所以按照上面的对齐条件,这个成员应该按照对其参数min(sizeof(long), 8) = 8字节来对齐,所以把这个成员存放在 0~7 内存单元中。

    然后 short型变量b,在64位地址空间中,short型占2个字节,所以按照上面的对齐条件,这个成员应该按照对其参数min(sizeof(short), 8) = 2字节来对齐,所以把这个成员存放在 8~9 内存单元中

    然后 int型变量c,在64位地址空间中,int型占4个字节,所以按照上面的对齐条件,这个成员应该按照对其参数min(sizeof(int), 8) = 4字节来对齐,所以把这个成员存放在 12~15 内存单元中(10,11单元都不能被4整除)。

    然后 int型变量d,在64位地址空间中,指针型占8个字节,所以按照上面的对齐条件,这个成员应该按照对其参数min(sizeof(int), 8) = 8字节来对齐,所以把这个成员存放在 16~23 内存单元中。

    然后 char型变量e,在64位地址空间中,char型占1个字节,所以按照上面的对齐条件,这个成员应该按照对其参数min(sizeof(char), 8) = 1字节来对齐,所以把这个成员存放在 24 内存单元中。

    然后整个结构体的长度必须为所有对齐参数的整数倍,当前长度为25,不是所有对齐参数整数倍,必须调整为32,才是所有参数整数倍。

    所以这个结构体的长度为32。

    举例2: 在32位操作系统中的大小。
      struct t{ 
          char a; 
          int b; 
      }; 
      struct s{ 
         char c; 
         struct t d; 
         char e; 
      }; 
    

    首先确定t的大小为8,它的所有成员使用的对齐参数最大为4。

    再考察s:
    首先 char 型变量c,在32位地址空间中,char型占1个字节,所以按照上面的对齐条件,这个成员应该按照对其参数min(sizeof(char), 8) = 1字节来对齐,所以把这个成员存放在 0 内存单元中。

    然后 struct t型变量d,在32位地址空间中,struct t占8个字节,所以按照上面的对齐条件,这个成员应该按照对其参数4 字节来对齐,所以把这个成员存放在 4~11 内存单元中。

    然后 char型变量e,在32位地址空间中,char型占1个字节,所以按照上面的对齐条件,这个成员应该按照对其参数min(sizeof(char), 8) = 1字节来对齐,所以把这个成员存放在 12 内存单元中。

    然后整个结构体的长度必须为所有对齐参数的整数倍,当前长度为13,不是所有对齐参数整数倍,必须调整为16,才是所有参数整数倍。

    所以此结构体大小为16.

举例3
union uti {
    int n;
    double g;
    char ch[9];
} struct srt {
    float xy;
    union uti uv;
} aa;

union中最大字节对齐类型为double,8字节。所以struct中应以double为标准对齐,并且分配给union的空间应该>=9字节,综上,float需要一个8字节存储,union需要两个8字节存储,共需3*8=24字节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值