结构体大小计算

时间:2024-01-23 19:48:36

应用场景:计算一个结构体的大小

请看如下代码:

结构体大小计算-结构体对齐_偏移量

计算结构体A的大小,按照我们以往的理解,a1,c1为int类型,b1为char类型,则其大小应该为 4byte*2+1byte=9byte ,但是我们可以看到实际上编译器计算的大小为12byte。

这是为什么呢?这就引出了今天要和大家分享的内容--结构体大小的计算-结构体对齐。

首先向大家介绍结构体的对齐规则:

1.第一个成员在与结构体变量偏移量为0的地址处,也就是说第一个成员的位置就是结构体变量的开始地址。

2.其余的成员变量都要对齐到对齐数的整数倍地址处。

在此给出对齐数的概念:

是编译器默认的一个对齐数与该成员大小的较小值。

以VS编译器为例,其默认对齐数为8

3.结构体总的大小为所有成员最大对齐数的整数倍。

举例向大家说明,以前面的struct A为例,编译器为VS,则默认对齐数为8

结构体大小计算-结构体对齐_偏移量_02

首先首个成员a1在结构体地址偏移量为0地址处,大小为4byte

成员b1在结构体地址偏移量为4地址处,判断是否为对齐数的整数倍。

成员c1在结构体地址偏移量为5地址处,其对齐数为4,偏移地址不为对齐数整数倍,继续向后偏移,直至偏移量为8位置处,向后4byte。

全部成员分析完毕,再看整个结构体的大小,大小为12byte,所有成员最大对齐数为4,结构体的大小是成员最大对齐数的整数倍,分析完毕,否则继续向后偏移,直至满足条件为止。

再来看一道题目:

如下的结构体:

struct A{

 long aa;

 short bb;

 int cc;

 int *dd;

};

请问在64位编译器下用sizeof(struct A)计算出的大小是多少?( )

图解:

结构体大小计算-结构体对齐_结构体_03

在vs当中验证一下:

结构体大小计算-结构体对齐_结构体大小计算_04

结果正确!

在这个题目中需要特别注意的是指针类型的成员变量,在32位编译器中,任意类型的指针变量都是4byte,而在64位编译器中,任意类型的指针变量均为8byte。这一点在计算结构体大小时需要特别注意一下。

知道如何计算结构体大小之后,那么为什么会有这种对齐的机制呢?

1.平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

2. 性能原因: 数据结构(尤其是栈)应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

总体来说:

结构体的内存对齐是拿空间来换取时间的做法。

感兴趣的话还可以下来查阅更多的相关资料。

可以使用#pragma 预处理指令,改变默认对齐数。

e.g:#pragma pack(8)//设置默认对齐数为8

       #pragma pack()//还原为默认对齐数

以上就是本次分享的全部内容,有错误欢迎指正!希望对大家有所帮助^-^