『C/C++』结构体内存对齐问题
初始的问题
先来看一个问题,对于下面这两个结构体,它们的大小是一样的吗?
1 | struct x |
1 | struct y |
你可能认为它们是一样的,但实际上是不一样的,一个是24,另一个是16
也据说是:结构体的大小并不是简单地将每个结构体成员的大小相加就能得到
如何计算结构体大小
首先我们要了解各种基本类型的大小
Type | sizeof(Type) |
---|---|
char | 1 |
short | 2 |
float | 4 |
int | 4 |
long | 4 |
long long | 8 |
double | 8 |
long double | 16 |
一般情况
-
后声明的类型永远认为结构体是按照自己的类型来的(找当前类型大小的最小倍数位置存放)
-
整个结构体补全到最大类型的整数倍
在第一个例子中
先声明了char类型,占用了1字节
然后声明int类型,他发现前4个字节有部分被占用了(无法使用),就跳过4个字节声明了自己,占用4字节
然后声明double类型,前8个字节有被占用,跳过8个字节声明自己,占用8字节
总计16字节,是8的倍数,所以结果为16
在第二个例子中
先声明char占用1字节
然后声明double,前8字节被占用,跳过前8字节声明自己,占用8字节
最后int占4字节
总计20字节,不是8的倍数,补到24
设置了对齐数的情况
-
每次都找
min(对齐数,类型大小)
的最小倍数位置存放 -
整个结构体补全到
min(对齐数,最大类型大小)
的整数倍
很多文章中有默认对齐数这种说法,就是说对齐数默认是设置了的,并认为在Windows中为8,在Linux中为4
但在我用的 MinGW-W64-builds-4.3.5 中貌似没有这个东西,因为我的测试结果与Linux gcc没有默认对齐数(内赋gcc官方大佬邮件)中的相同
如何设置对齐数
要设置编译器的对齐数,我们需要借助于以下预处理命令:
1 |
如果在该预处理命令的括号内填上数字,那么对齐数将会被设置为对应数字
如果不在括号内填写数字,那么会恢复为未设置对齐数状态
对齐数只能为2的次幂
嵌套结构体
如果 A 嵌在 B 中,那么计算 B 的大小相当于计算把引入 A 的那一行替换成 A 中的内容
的新结构体的大小
最省空间策略(重要)
先声明类型空间大的,再声明类型空间小的
(数组看作是连续的多个声明)
当然,还可以使用位域,但这东西真的把我给看懵圈了😂