C/C++ struct中字节对齐问题

C/C++ struct中字节对齐问题

规则1: 结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员放在offset为该数据成员大小的整数倍的地方(比如int在32为机器为4个字节,则每个int变量都是从4的整数倍地址开始存储)

规则2: 如果一个结构体B里面嵌套另一个结构体A,则结构体A应从offset为A内部最大成员的整数倍的地方开始存储。(例如struct B里面有struct A, struct A里面有char, int, double等成员,那A应该从8的整数倍开始存储。),结构体A的成员的对齐规则仍然满足原则1、原则2

原则1: 结构体A (struct A)所占的大小为该结构体成员内部最大元素的整数倍,不足的对齐;
原则2:当Struct B中嵌套有Struct A, 不是字节将结构体的成员直接移动到结构体B中

案例分析:
例1

struct A {
    int a;
    short b;
};
/** 
  * 内存对齐规则:
  * 按最长的类型的长度为最长长度
  * 4*0 = 0 所以从 0 位置开始放
  * 2*0 = 0 0位置已经有内容
  * 2*1 = 2 2位置已经有内容
  * 2*2 = 4 4位置空,可以存放
  * short长度 为2 而基准长度为4,因此 需要将剩余的两字节补空
  * 故 A大小为8字节
  * a a a a
  * b b - - 
  */ 
 printf("%d\n",sizeof(A));//8

例2

struct B{
   double a;
   short b;
   int c;
};
/** 
  * 最长基准长度为8
  * 8*0 = 0 放于0位置起的8个字节
  * 2*0 = 0 此处有内容
  * ...
  * 2*4 = 8 此处空闲可以存放 8-10用于存放 short
  * 4*0 = 0 此处已经有内容
  * ...
  * 4*3 = 12 此处可以存放 12-15
  * a a a a a a a a
  * b b - - c c c c
  * 所以B共占用 16字节
  */
 printf("%d\n",sizeof(B)); 

例3

struct C{
  short a;
  double b;
  int c;
};
/** 
 * 最长基准长度为:8
 * 2*0 = 0 0-1位置用于存放a
 * 8*0 = 0 此处已有内容
 * 8*1 = 8 8-16位置用于存放b
 * 4*0 = 0 此处已有内容
 * 4*3 = 12 12-16存放c
 * a a - - - - - -
 * b b b b b b b b
 * c c c c - - - -
 */
printf("%d\n",sizeof(C)); //24

例4

struct D{
  int a;
  double b;
};
struct E{
  short a;
  int b;
  D c;
};
/** 
   * 当结构体内部嵌套结构体时,以两个结构体内部最长的类型为基准长度
   * 此处结构体D与E最长的长度为D中的double,因此基准长度为:8
   * 2 * 0 = 0 0-1位置存放E.a
   * 4 * 0 = 0 
   * 4 * 1 = 4 4-7位置存放E.b
   * 8 + 4 * 0 = 8 8-11位置存放D.a
   * 8 + 8 * 0 = 8
   * 8 + 8 * 1 = 16 16-23位置存放D.b
   * 
   * 内存结构
   * E.a  E.a  ---  ---  E.b  E.b  E.b  E.b
   * D.a  D.a  D.a  D.a  ---  ---  ---  ---
   * D.b  D.b  D.b  D.b  D.b  D.b  D.b  D.b  
   * 
   * 因此struct E 共占24个字节
   */
  printf("%d\n",sizeof(E)); //24

参考:
https://blog.csdn.net/annjeff/article/details/89227976

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值