c++对象长度之内存对齐(2)

内存对齐

在VC++6.0中,类和结构体中的数据成员是根据它们在类或结构体中出现的顺序来依次申请申请内存空间的,由于内存对齐的原因,它们并不一定会像数组那样连续地排列。由于数据类型的不同,因此占用的内存空间大小也会不同,因此占用的内存空间大小也会不同,在申请内存时,会遵守一定的规则。

要找对齐的话,我个人感觉应该先找到
编译器的指定对齐值因为结构体中的当前数据成员类型长度为M,指定的对齐值是N,那么实际的对齐值为q=min(M,N),其成员的地址安排在q的倍数上。

但是,并非设定了默认对齐值就将结构体的对齐值锁定。如果结构体中的数据成员类型最大值为M,指定的对齐值是N,那么实际对齐值为q=min(M,N)

三准则如下:
a.数据成员对其规则:结构(或联合)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int 在32位机为4字节则要从4的整数倍地址开始存储)

b.结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素的整数倍地址开始存储.(struct a里存有 struct b,b里有 char ,int ,double 等元素,那b应该从8的整数倍开始存储.)

c.收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐

来举一个最简单的例子吧,请看截图

例题a

在这里插入图片描述
这个int 类型数据占据四个存储单元是 0~ 3(四个字节),但由于double 是8个字节,根据准则a,那么我们需要填充四个字节,从存储单元8开始填double b,即存储单元8~15是b的数据,所以存储单元0 ~15是16个字节

例题b

在这里插入图片描述

此例题说明 准则二 和准则三的作用

在对象bq中,有 int a,double aa,char c,根据三准则中准则一,首先int a占 4字节(存储单元0 ~ 3);然后根据准则二 double aa 排列的存储单元是 8 ~ 15,char c排列的存储单元是 16;根据准则三收尾功能填充,则对象bq占了24字节(最后0 ~ 23占了24个字节);

然后da对象中,有 char aa ,b a,int aaa,根据三准则中准则一,首先char aa 占一字节(存储单元0);然后 根据准则二b a排列的存储单元是 8 ~ 31,int aaa排列的存储单元是32~35;根据准则三收尾功能,填充36 ~39(最后0 ~ 39占了40个字节);

提示:当结构体中以数组作为成员时,将根据数组元素的长度计算对齐值,而不是按数组的整体大小去计算,例题如下:

例题c

在这里插入图片描述

解释:
在对象bq中,有double a[2],int aa,char c,根据三准则中准则一,首先double a[2]占 16字节(存储单元0 ~ 15);然后根据准则一 int aa 排列的存储单元是 16 ~ 19,char c排列的存储单元是 20;根据准则三收尾功能填充,在这里我们需要讨论了,如果用double 数组总长度来带入准则三的话,那么应该为32,所以此排除;如果用double单个元素的长度来带入准则三的话,那么符合
当然在这里还有同学肯定有疑问,如果我以 int aa 带入准则三呢?(因为数组这种东西比较特殊,跟其它的有点不一样,万一特殊呢?对吧?)
所以的话,我已经准备好下面的东西来解释了

在这里插入图片描述
哎呀,把int aa改成了char aa,还是24呀,那么是不是就验证了我的说法呢?

好啦,这里告一段落,给大家来个题目,下面会输出什么呢?

class b
{
    
    
    double a; 
    char c;
};
void main() {
    
    
    b bq;
    int lengthbq = sizeof(bq); 
    cout << lengthbq
#pragma pack(N)用法如下所示:

在这里插入图片描述

在这里插入图片描述
VC++6.0 中可使用预编译指令#pragma pack(N)来调整对齐大小,当上面把对齐值改过后,它并非原来的16字节,而是变成9字节。

使用pack修改对齐值也并非一定会生效,与默认对齐值一样,对需要参考结构体中数据成员类型。当设定的对齐值大于结构体中的数据成员类型大小时,此对齐值是无效的。对齐值的计算流程换种说法是:将设定的对齐值与结构体中最大的基本类型数据成员的长度进行比较,取两者之间的较小值。

如下在这里插入图片描述
验证以上说法

猜你喜欢

转载自blog.csdn.net/CSNN2019/article/details/111167512