※ – 内存对齐原则
1、数据成员对齐规则:结构体(Struct)【或联合体(Union)】的数据成员,第一个数据成员防止offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存储)。
min(当前开始的位置m、n)m=9 、n=4
9 、10、11、12
2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。
struct a里存有 struct b,b里有char、int、double等元素,
那b应该从8的整数倍的地址开始存储。
3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。
1字节 = 8位 【1Byte = 8bit】
double | 8字节 |
int | 4字节 |
float | 4字节 |
short | 2字节 |
char | 1字节 |
bool | 1字节 |
1、结构体AStruct及内存对齐说明
struct AStruct {
double a; // 8字节 - [0...7]
char b; // 1字节 - 8是1的整数倍, 故存储空间为[8]
int c; // 4字节 - 9不是4的整数倍,故存储空间首地址向后偏移,为[12 13 14 15]
short d; // 2字节 - 16是2的整数倍, 故存储空间为[16 17]
} aTest; // aTest占用内存区间为[0 ... 17],故大小为18字节,取最大元素double的整数倍,故aTest大小为24字节
2、结构体BStruct及内存对齐说明
struct BStruct {
double a; // 8字节 - [0...7]
int b; // 4字节 - 8是4的整数倍, 故存储空间为[8 9 10 11]
float c; // 4字节 - 12是4的整数倍, 故存储空间为[12 13 14 15]
short d; // 2字节 - 16是2的整数倍, 故存储空间为[16 17]
bool e; // 1字节 - 18是1的整数倍, 故存储空间为[18]
}bTest; // bTest占用内存空间为[0 ... 18],大小为19,取最大元素double 8字节的整数倍,故bTest大小为24字节
3、结构体CStruct及内存对齐说明
struct CStruct {
double a; // 8字节 - [0...7]
int b; // 4字节 - 8是4的整数倍, 故存储空间为[8 9 10 11]
char c; // 1字节 - 12是1的整数倍, 故存储空间为[12]
short d; // 2字节 - 13不是2的整数倍, 故存储空间首地址向后偏移,为[14 15]
int e; // 4字节 - 16是4的整数倍, 故存储空间为[16 17 18 19]
struct AStruct structA; // 24字节- 20不是24的整数倍,故存储空间首地址向后偏移,为[24 ... 47]
struct BStruct structB; // 24字节- 48是24的整数倍,故存储空间为[48 ... 71]
bool f; // 1字节 - 72是1的整数倍,故存储空间为[72]
}cTest; // cTest占用内存空间为[0 ... 72],大小为73,取最大元素double(8字节)的整数倍,80字节
之所以有偏移及对齐:空间换取时间,提高代码执行效率
补充:终端命令说明
x/nuf <addr>
n:
表示要显示的内存单元的个数———————————————-
u:表示一个地址单元的长度
b:表示单字节
h:表示双字节
w:表示四字节
g:表示八字节
———————————————-
f:表示显示方式,可取如下值:
x:按十六进制格式显示变量
d:按十进制格式显示变量
u:按十进制格式显示无符号整型
o:按八进制格式显示变量
t:按二进制格式显示变量
a:按十六进制格式显示变量
i:指令地址格式
c:按字符格式显示变量
f:按浮点数格式显示变量