C语言字节对齐的一些知识点

本文详细介绍了不同系统下数据类型长度的变化,探讨了字节对齐的重要性及其对CPU访问数据效率的影响。同时,文章提供了处理字节对齐问题的方法,包括编译器规则和特定情况下的对齐策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不同系统下数据类型长度不一样

Data TypeILP32(32位linux)ILP64LP64(64位linux)LLP64(64位windows)
char8888
short16161616
int32643232
long32646432
long long64646464
pointer32646464

基本概念

许多计算机系统对基本数据类型合法地址做出了一些限制,要求某种类型对象的地址必须是某个值K(通常是2,4或8)的倍数。这种对齐限制简化了形成处理器和存储器系统之间的接口的硬件设计。对齐跟数据在内存中的位置有关。如果一个变量的内存地址正好位于它长度的整数倍,就被称做自然对齐。

为什么要字节对齐

CPU访问数据的效率。

如何处理字节对齐

编译器的规则:

  1. 数据类型自身对齐值:为指定平台上基本类型的长度。
  2. 结构体或者类的自身对齐值:为成员中自身对齐值最大的那个值。
  3. 指定对齐值:#pragma pack(value)。
  4. 数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中较小的值。

对于标准数据类型,它的地址只要是其长度的整数倍即可。非标准数据类型的原则:

  • 数组:按照基本数据类型对齐,第一个对齐了后面的自然也对齐了。
  • 联合:按其包含的长度最大的数据类型对齐。
  • 结构体:结构体中每个数据类型都要对齐。

字节对齐的隐患

比如在强制类型转换的时候:

unsigned int i = 0x12345678;
unsigned char *p = NULL;
unsigned short *p1 = NULL;

p = &i;
*p = 0x00;
p1 = (unsigned short *)(p + 1);
*p1 = 0x0000;

最后两句代码,从奇数边界去访问unsigned short型变量,显然不符合对齐的规则。

如何查找与字节对齐方面的问题

如果出现对齐或者赋值问题首先查看:

  1. 编译器的大小端设置
  2. 体系是否支持非对齐访问
  3. 若支持看设置了对齐与否,如果没有则看访问时需要加某些特殊的修饰来标志其特殊访问操作

 

https://blog.youkuaiyun.com/cclethe/article/details/79659590

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值