内存对齐 联合体 位段式与截断 补码
CPP中的内存对齐
内存对齐的原因之一
计算机硬件通常是按字或双字边界来访问内存的。如果数据没有对齐,可能需要多次内存访问,从而降低了速度。
内存对齐
- 结构体对齐:结构体本身的对齐要求通常是其成员中对齐要求最大的那个———可以理解为,结构体大小需要是其成员中最大对齐数的倍数。成员的偏移量,需要是自身和默认对齐数中,较小哪一位的倍数。
- 拿下方的实验代码为例,double_number的对齐数是8,但存储完int_number后,此时地址的偏移量是3(从0开始),需要填充成员中最大对齐数的倍数处,这里就是8。因此,结构体的实际大小可能大于其成员大小之和。
- 联合体对齐:联合体(union)的对齐要求是其成员中对齐要求最大的那个。不过,由于联合体中的所有成员共享同一块内存,因此联合体的大小等于其最大成员的大小。
对齐数的计算
- 第一个成员在与结构体变量偏移量为0的地址处。
- 其他成员变量要对齐到对齐数的整数倍的地址处——对齐数 = 编译器默认的对齐数(如VS2019下是8)与 该成员大小的 较小值。
- 结构体总大小为成员中最大对齐数的整数倍(如标题中24%8==0)。
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处。
位段式的结构体
位段是C语言中一种特殊的结构体成员类型,它允许使用比字节更小的单位来存储数据。
位段在结构体中定义时,需要指定一个整数类型(通常为unsigned int或int),并在冒号后面指明位数。位段式结构体通常用于表示具有多个独立标志位或具有较小范围值的数据,从而节省内存空间。
例如:
1 |
|
实验代码
1 |
|
实验结果分析
- 符号位:最高位(最左边的一位)表示符号,0 表示正数,1 表示负数。
- 数值位:其余的位用于表示数值大小。
110(6):
- 补码形式,符号位 1 表示负数。
- 取反 001,加 1 得 010,所以是 -2。
101(5):
- 补码形式,符号位 1 表示负数。
- 取反 010,加 1 得 011,所以是 -3。
内存对齐 联合体 位段式与截断 补码
https://weihehe.top/2024/07/05/内存对齐/