结构体的字节对齐(超详细:规则+例子+原因)

结构体的字节对齐问题

遵循的规则:
  1. 某数据类型的变量存放的地址需要按有效对齐字节剩下的字节数可以被该数据类型所占字节数整除,char可以放在任意位置,int存放在剩下字节数可以被4整除的位置。这个对齐规则是内部一定的

  2. 结构体的大小一定要为有效对齐值的整数倍

  3. 当没有明确指明时,以结构体中最长的成员的长度来对齐,注意!数组成员个数并不影响有效对齐值,只是数组类型大小和其他成员比较取最大。但是当然数组成员总占用内存也要遵循字节对齐

  4. 当用#pragma pack(n)指定时,以n和最长成员中长度较小的值来对齐

  5. 当用

    __attribute__((__n__))
    

    指明时,强制按照该值来对齐

  6. 类似:char f1:3 这样的语句是位结构,就是本来char类型是占用一个字节,但是现在让char型的f1只占用3位。所以:

在这里插入图片描述

sizeof(CVTE)=8,由于C,V这里都是4位,T为8位,合起来为2个字节,为了字节对齐,E只能放在可以被4整除的地址,所以剩下的2并不能被整除,所以要补齐2,再放E,所以一共8个字节。

典型例子:
  • 例1:在这里插入图片描述

结果并不是9,由于最后的大小要为int(max)的整数倍,所以是12

  • 例2:

在这里插入图片描述

由于2<4,所以按2对齐。所以1+1+2+2+1=7,要为2的倍数,所以结果为8

如果指定的pack为8,那么还是按4来对齐,所以结果为12了

  • 例3:

在这里插入图片描述

不用比较大小了,就是按8对齐。所以1+7+4+1=13.要为8的倍数,所以结果为16

  • 例4:

在这里插入图片描述

最大成员数值并不是8,由于数组的比较数据类型,所以最大的还是4,按4对齐。所以1+3+4*2+4+4=20,可以被4整除。如果这里数组的总大小是9,那么没有和自己数据类型对齐,所以要补齐数组大小为12.

需要内存对齐的原因:
  • 平台原因:某些平台只能在特定的地址处访问特定类型的数据
  • 性能原因:
    1. 数据结构应该尽可能在自然边界上对齐
    2. 访问未对齐的内存,处理器需要作两次内存访问。而对齐的内存仅需要访问一次
C语言结构体字节对齐规则是根据结构体中的成员变量的类型和对齐值来确定的。对于一个结构体来说,它的自身对齐值是结构体中所有成员变量中的最大对齐值。而结构体的有效对齐值是结构体的自身对齐值和操作系统的对齐值中的较小值。 在给定的例子中,结构体A中包含了一个short型变量b、一个int型变量c和一个char型变量a。根据引用\[2\]中的解释,short型变量占用2字节,int型变量占用4字节,char型变量占用1字节。因此,结构体A的自身对齐值为4字节。 根据引用\[3\]中的解释,结构体A的有效对齐值是结构体的自身对齐值和操作系统的对齐值中的较小值。在这个例子中,操作系统的对齐值也是4字节。所以,结构体A的有效对齐值也是4字节。 因此,根据C语言结构体字节对齐规则结构体A中的成员变量a和b要组成4个字节,以便与成员变量c的4个字节对齐。由于成员变量a只占用1个字节,所以在a和b之间会有一个字节的空隙。 总结起来,C语言结构体字节对齐规则是根据结构体中的成员变量的类型和对齐值来确定的,以保证结构体的对齐要求和内存的高效利用。 #### 引用[.reference_title] - *1* *2* *3* [C语言结构体——关于内存字节对齐图文详解](https://blog.csdn.net/qq_62932195/article/details/125821103)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值