字节对齐

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设置

 

以上是关于字节对齐的主要内容,如果未能解决你的问题,请参考以下文章

字节对齐方法

字节对齐

指定字节对齐方式

仔细讨论 C/C++ 字节对齐问题

#pragma pack(非常有用的字节对齐用法说明)

关于字节对齐的理解