结构体大小的计算(内存对齐)

对齐数

        在了解结构体大小是如何计算的时候,我们首先要了解一个概念——对齐数

        下面我们先来看三个实际例子,仔细观察三者的不同之处:

 

看到这里你或许会疑惑,为什么三个代码只是变量位置不一样,为什么结构大小会改变呢?这样子是不是造成了空间的浪费呢?

在这里不得不提到一个概念——内存对齐,这里又会衍生出两个问题:

  1. 问题一:为什么要内存对齐?
  2. 问题二:内存对齐有哪些规则?

 下面我们来解决问题:

        问题一:为什么要内存对齐?

        答:内存对齐实际上就是牺牲了空间换取效率的方法,我们都知道计算机在查找数据的时候可以一个一个字节的查找,这种方法有个缺陷——查找效率很慢,我们可以看看第三个实例,首先为结构体变量c和b都分配了1个字节,然后才为结构体整形变量i分配4个字节,一个字节一个字节的查找对于找到b和c来说轻而易举,但是对于i来说呢?需要访问完整的i我们才能找到i占用的存储空间,对于找i来说,我们的指针需要移动3次才能访问到完整的i,内存对齐的意义是什么呢?就是为了可以4个字节4个字节的去找,从而提升查找效率,实现了用空间换取时间。

        问题二:内存对齐有哪些规则?

        答:1.第一个成员在结构体偏移量为0的地址处。

                2.其他成员要对齐到自己对齐数的整数倍的地址处。

                3.结构体大小为对最大对齐数的整数倍(编译器有默认对齐数,每个成员都有一个对齐数)

                4.如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍,嵌套的结构体大小不变,结构体的整体大小为所有最大对齐数(含嵌套结构体对齐数)的整数倍。

下面我们根据一个表格进行进一步学习。

        

 现在我们运用实例进行讲解:

 

 

最后,讲解一下关于对齐数的调整:

我们一般用 #pragma pack(n)来设置默认对齐数,n为自己设置的默认对齐数 
当再次使用 #pragma pack() 的时候就恢复了原平台的默认对齐数大小 

猜你喜欢

转载自blog.csdn.net/m0_60338933/article/details/124186934