网站已经改版为Wordpress版本,这里是旧版本的快照,请不要在页面中留言.

浅谈C++结构体和类,对象的大小该如何计算?《二》结构体对齐


   文章列表:

       · 浅谈C++结构体和类,对象的大小该如何计算?《一》

       · 浅谈C++结构体和类,对象的大小该如何计算?《二》结构体对齐

       · 浅谈C++结构体和类,对象的大小该如何计算?《三》结构体内部含有数组和结构体等



    书接上回,在上一篇 浅谈C++结构体和类,对象的大小该如何计算?《一》 中的最后,我们提出了一个问题,对于结构体:

struct STest{
    double da;//8字节大小
    int    ib;//4字节大小
    short  sc;//2字节大小
};

STest的大小用sizeof计算的结果是16而不是8+4+2=14字节,这是为什么?

这是因为结构体本身也是一种数据类型,当然他也有对应的字节对齐处理,这里我们将会讨论一下对齐值对结构体整体大小的影响,如果按照VC++6.0默认的8字节对齐,那么对于一个结构体来说他的对齐值依然满足公式q=Min(M,N) (VC++6.0中N=8),但是需要注意的是这里的M应该是结构体中的数据成员类型的最大值,就像结构体STest,他的对齐值按照最大的数据成员double da,对齐值也就是 8Byte,这样一来可以计算出结构体STest的对齐值为8,所以编译器在STest的最后一个成员short sc后面有增加了2个字节用于填充结构体,使得整体大小为16字节,这样就满足了对齐的要求。

      通过上面的介绍可以看出,结构体的对齐值是根据结构体内部最大的成员长度动态调整的,可不是固定的8字节,也可以是4字节。

      在C++中,虽然存在默认的对齐值,但是这个默认值也是可以修改的,我们可以使用预编译指令 #pragma pack(N) 来指定对齐大小,例如我们下面的代码,将对齐值设置为1字节:

#pragma pack(1)
struct STest{
    double da;//8字节大小
    int    ib;//4字节大小
    short  sc;//2字节大小
};


运行结果如下图所示,这里的sizeof计算出的结构就是 14字节了:                  

      经过预编译指令后,将对齐值调整为1字节,根据对齐规则,q=Min(4,1)得出对齐值为1字节,既然是1字节,辣么就不用想了,直接就是14字节的大小了。

      但是要注意的是,你使用#pragma pack(N)设置的对齐值可不一定会生效的,这是因为q=Min(M,N),要知道你的N要是太大的话~~q最终还是等于M的,就像你设置对齐值为128,根本没啥用嘛= =,对齐值的计算流程总的来说:将设定的对齐值与结构体中最大的基本类型数据成员的长度进行比较,取两者之间的较小者。

      当结构体中以数组作为成员的时候,将会根据数组 元素类型 的长度计算对齐值,而不是按照数组的整体大小去计算。

      今天先写到这里,在下篇文章中我们在慢慢讨论含有数组的结构体的对齐值的计算.


  • 标签:
  • C++结构体内存对齐
  • C++内存对齐
  • 内存对齐
网站已经改版为Wordpress版本,这里是旧版本的快照,请不要在页面中留言.