C - 结构体字节对齐问题

C - 结构体字节对齐问题

 

        关于C语言中的结构体字节对齐问题,在《C与指针》一书中提到,但是似乎没有说清楚,还是我理解不完全?所以,根据书上和网上资料,总结一些关于C语言中的结构体字节对齐的知识。这里的讨论和代码,都在VS2010下,GCC不太熟悉就不说了;-(

 

(1)什么是字节对齐[1]

对齐规则

        结构体中一个变量占用 n 个字节,则该变量的起始地址必须能够被 n 整除,即:存放起始地址 % n = 0,对于结构体而言,这个 n 取其成员中的数据类型占空间的值最大的那个。(这里n可以称为对齐值)

        补充:结构体的长度必须为结构体的实际对齐值(自身对齐值和编译器默认对齐值中最小的一个)的整数倍,不够就补空字节。

 

(2)为什么要字节对齐[1]

        内存空间是按照字节来划分的,从理论上说对内存空间的访问可以从任何地址开始,但是在实际上不同架构的 CPU 为了提高访问内存的速度,就规定了对于某些类型的数据只能从特定的起始位置开始访问。这样就决定了各种数据类型只能按照相应的规则在内存空间中存放,而不能一个接一个的顺序排列。

        举个例子,比如有些平台访问内存地址都从偶数地址开始,对于一个 int 型(假设 32 位系统),如果从偶数地址开始的地方存放,这样一个读周期就可以读出这个 int 数据,但是如果从奇数地址开始的地址存放,就需要两个读周期,并对两次读出的结果的高低字节进行拼凑才能得到这个int 数据,这样明显降低了读取的效率。

 

(3)如何进行字节对齐[1,2]

        参考[2],每个数据类型的变量(或称数据对象data object)都有一个对齐值(alignment-requirement),即sizeof(data type)。例如char类型变量的对齐值是1,int、long、float的对齐值是4,long long、double的对齐值则是8,单位都是字节。而结构体的对齐值则是成员变量中占用空间最大的那个变量的大小。

        根据上述结论,“一个变量占用 n 个字节,则该变量的起始地址必须能够被 n 整除,即:存放起始地址 % n = 0”,那么char类型变量的地址必须被1整除,int、long、float的地址必须被4整除,而long long、double必须被8整除。

        由于结构体里成员变量的地址是按照顺序存储的,因此不能保证每个成员变量满足上述规则,所以有些成员变量的地址之前或之后需要填充一些字节

        至于要填充多少字节,跟每个变量实际的对齐值有关。确定实际的对齐值,有2条规则:

1、每个编译器有默认的对齐值,VS2010中默认是8,可以在代码中加入#pragma pack(n)指令,告诉编译器默认对齐值的大小,这里的n必须是1,2,4,8,16之一。(

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值