字节对齐
Posted contradictory-man
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字节对齐相关的知识,希望对你有一定的参考价值。
什么是字节对齐
cpu在访问存储器的时候,通常从存储器中取出固定长度的字节数。
计算机系统为了配合提高cpu的访问效率,也规定数据类型通常会是2或4的倍数,以简化cpu做取数据动作的复杂程度。
cpu取数据是以地址为单位的,如要取出4个字节,要么就是取0~3,或4~7。如果数据在这种时候跨地址存储,就需要cpu进行二次,甚至三次做取数据的动作,大大消耗了cpu资源。
因此,大多数编译器在操作内存空间的时候,都通过填充空白区间,对数据进行补齐,方便cpu对下一个元素操作时,能够直接从该元素长度整数倍的地址开始读取元素。
结构体中字节对齐的方法
保证下一个元素所在的首地址,是该元素长度的整数倍。
如果没有指定对齐值,则要求整个结构体数据长度为结构体中最长数据类型长度的整数倍。
如果有指定对齐值,则要求所有元素起始地址是指定对齐值得整数倍,且整体长度为指定对齐值的整数倍。
如果指定对齐值大于元素本身的长度,该元素在对齐时,按自身长度的整数倍地址对齐。
pragma
如:
struct A
{
char a; //1字节
int b; //4字节
short c;// 2字节
}
a占1个字节,前方不需要补齐。
b占4个字节,b需要它的首地址是4的整数倍。因此,需要在a之后补3个字节。
此时c前面已经有了8个字节,他的首地址是8,是本身长度2的倍数,前方不需要补齐。
在没有指定对齐值的情况下,要求结构体总长度是最长元素的整数倍,现在一共有10个字节,需要在最后补齐2个字节,达到12。
即:a(1字节) 空空空 b(4字节) c(2字节) 空空
而如果指定对齐值为1的话,
所有元素的首地址本身就是1的整数倍,就不需要再进行字节补齐了。
即:a(1字节) b(4字节) c(2字节)
Qt中的设置指定对齐值
#pragma pack(push) //保存对齐状态
#pragma pack(1)//设定为1字节对齐
...
...
...
#pragma pack(pop) // 恢复先前的pack设置
以上是关于字节对齐的主要内容,如果未能解决你的问题,请参考以下文章