· 浅谈C++结构体和类,对象的大小该如何计算?《二》结构体对齐
· 浅谈C++结构体和类,对象的大小该如何计算?《三》结构体内部含有数组和结构体等
书接上回,上一篇文章中大家已经知道了结构体对齐值的计算方法,在最后留下了【结构体中含有数组类型数据时,结构体的对齐值计算】的问题,本篇文章中将会详细的介绍含有数组的结构体以及结构体内嵌结构体是如何计算对齐值的。
· 结构体含有数组类型的对齐
OK,我们开始吧。当结构体中以数组作为成员的时候,将会根据 数组元素 的长度计算对齐值,而不是根据数组的整体长度来计算,例如下面的代码:
Struct{ Char cChar; //占用一个字节内存 Char cArray[4]; //占用多少字节内存呢? Short sShort; //应该占用2字节内存 }
按照对齐的规定,cChar与cArry他们都是char类型的数据,内存对齐没有缝隙,不需要插入空白的数据。但是当cArray与sShort对齐的时候,cChar与cArray已经在内存中占用了5个字节,此时按照结构体中当前的数据类型short进行对齐的时候,就需要在cArray后面在插入一个字节就OK了,其结构如下图所示:
结构体内部的数据成员已经对齐了,下面就是处理结构体本身的对齐值问题了。根据结构体中的数据成元类型得到,最大的数据成员sShort占2个字节,其余成员都是1字节的大小,在默认的情况下,对齐值为8,根据公式q = Min(M,N) 计算得出该结构体的对齐值为2,而此时结构体的总大小为8字节,也就是说无需填入数据即可满足对齐要求.
当结构体中出现结构体类型的数据成员的时候,不会将嵌套的结构体类型的整体长度参与到对齐值的计算中,而是以嵌套定义的结构体所使用的对齐值进行对齐计算,如下面的代码所示:
struct tagOne { char cChar; //占用1字节 char cArray[4]; //占用5字节 short sShort; //占用2字节 }; struct tagTwo { int nInt; //占用4字节 tagOne one; //占用8字节 };
在上面的结构体中,虽然tagOne占用了8字节大小,但是由于其对齐值为2,所以在计算tagTwo的对齐值的时候参数one的对齐值是2,所以根据对齐计算的公式q=Min(M,N)得出数据结构tagTwo的对齐值为4,占用了12个字节!而不是以8对齐占用16字节。
· 静态数据成员
当类中的数据成员被修饰为静态成员的时候,对象的计算方法又会发生变化。因为虽然静态数据成员是在类内部进行定义,但是它与静态局部变量是类似的,存放的位置和全局变量一致。只是编译器增加了作用域的检查,在作用域外不可见,同类对象将共享有静态数据成员的空间.