如果想出发,就不要等到明天!
全部博文(317)
分类: C/C++
2013-03-26 10:45:34
原文地址:C语言结构体对齐问题 作者:庖丁解犇
在说明对齐问题之前请看下面代码:
点击(此处)折叠或打开
在运行代码之前,请思考下输出值应该是多少?如果你的答案是8 12,那么恭喜你!
那么两个看似相同的结构体,大小差异为什么会这么大?这都是归因于计算机的字节对齐。
所谓字节对齐:
计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放。
下面引入几个关于对其的概念:
1.数据类型的字对齐:对于char 自对其为1字节,对于short 自对齐值为2字节,对于int float double自对齐值为4字节。
2.结构体(位域)的自对齐值为其成员中自对齐最大的值。
所谓自对齐值即 变量的起始地址%自对齐值==0.
下面分析下struct B:
假定结构体的开始地址为0x00,那么b的存储空间为0x00 ,0x00 %1==0,a的存储地址为多少呢?由于a需自对齐,必须使a的起始%4==0,同时必须紧靠b,容易得出a的起始地址为0x04。0x01-——0x03为结构体的填充字节,c的起始地址为0x08。根据上面的推断,那B的长度应该是10为什么会是12呢?请看概念2,结构体类型也有自对齐,是成员中自对齐的最大值既4。假如存在结构体B数组,为了保证第二个元素的自对齐,那么第一个元素的长度必须是12,既sizeof(struct B)==12.
既然系统有默认的对齐方式,那么对齐的方式在C语言中是否可以改变呢?答案是肯定的:
3.可以用#pragma pack(value)改变对齐的值。
4.当使用了#pragma pack(value)时,数据成员,结构体的对齐值为自对齐值和指定对齐值中的较小值
请看实列:
点击(此处)折叠或打开