C语言 day17
结构体-结构体的内存分配
引入
1 | struct data{ |
- 问:上面代码的输出结果为什么?5?
运行结果:
分析:char
一个字节,int
四个字节,为什么不是5字节呢?32位处理器一次只能处理32位,也就是4个字节的数据,64位处理器一次就能处理64位,即8个字节的数据。看图—>
由图可得,上面代码输出的是4字节。
结构体大小 >= 成员总大小
结构体内存对齐
对齐规则(重要)
步骤:
- 确定分配单位:每行应该分配的字节数,由结构体中最大的基本类型长度决定
- 确定成员的起始位置的偏移量:成员的自身基本类型的整数倍x(0到n),如果空间已经被使用了,则x+1继续偏移,直到遇到没有被使用的空间
- 收尾工作:确定结构体总大小,总大小为分配单位的整数倍,即开辟的行数乘以分配单位
例子:
1、
1 | struct data{ |
内存分布:
2、
1 | struct data{ |
内存分布:
3、
1 | struct data{ |
内存分布:
结构体嵌套结构体
1 | struct data1{ |
- 结构体变量
c
,作为了struct data2
的成员,叫做结构体嵌套结构体
案例1:
1 |
|
运行结果:
注意:
stu.c
是没意义的,因为对于计算机来说,他要操作的是数据,那你说stu.c
是个什么,取出来是什么?啥都不是,但是会打印出c中的第一个元素空间的内容。不要这样干就行了。
结构体嵌套结构体的内存对齐
先将嵌套的结构体进行上面的内存对齐,再将嵌套的结构体看成一个变量进行下面的步骤,其实跟上面的一样
- 步骤:
- 确定分配单位:每行应该分配的字节数,所有结构体中最大的基本类型长度。
- 确定成员的起始位置的偏移量:成员的自身基本类型的整数倍x(0到n),如果空间已经被使用了,则x+1继续偏移,直到遇到没有被使用的空间
- 收尾工作:确定结构体总大小,总大小为分配单位的整数倍,即开辟的行数乘以分配单位
1 | struct A{ |
内存分布:
1 | struct A{ |
内存分布:
指定对齐规则(强制类型对齐)
使用
#pragma pack
改变默认对齐原则格式:
#pragma pack(value)
注意:
value
只能是1、2、4、8等即2ⁿ;- 指定对齐值与数据类型对齐值相比取较小值。
步骤:
- 确定分配单位:每行应该分配的字节数,分配单位为
min(value,默认对齐字节)
。 - 确定成员的起始位置的偏移量:成员的自身基本类型的整数倍x(0到n),如果空间已经被使用了,则x+1继续偏移,直到遇到没有被使用的空间
- 收尾工作:确定结构体总大小,总大小为分配单位的整数倍,即开辟的行数乘以分配单位
- 确定分配单位:每行应该分配的字节数,分配单位为
案例:
1 |
|
分析:不加之前结构体总大小为12字节;加了#pragma pack(2)
之后结构体的总大小为8字节
结构体的成员顺序,会影响结构体的总大小;如果想节约空间,则可以把字节数差不多的类型放在一起,但是这样访问效率会下降。