对齐规则:
(i)结构体内 成员存储位置 的起始地址为 成员自身长度与默认对齐值 中的较小者的整倍数。
(ii)结构体A嵌套在结构体B内,则A在B内存储位置起始地址为 A内成员最长长度 的整数倍。
(iii)结构体本身的大小为 其内成员最长长度的整数倍。ps:若结构体A嵌套在结构体B内(即A是B的成员),则在计算B的大小时,以A内成员的最长长度替换A的长度进行计算。
ps :我使用的是windows 64位系统,默认对齐值为 8 Byte。 起始地址:为在该数据结构内的相对地址,第一个成员的相对起始地址为0。
举例解释说明:
struct A {
double a;
int b;
char c;
short d;
};
A.a : 根据规则(i),首先求出成员自身长度与默认对齐值中的较小者:k = min(sizeof(A.a), 8) = min(8, 8) = 8;A.a在A内的起始地址为k=8的整数倍,所以A.a在A内的起始地址为 k * 0 = 0,A.a存储范围为 0 ~ 7(double 占8Byte)。ps:地址0是结构体A内的相对地址
A.b :根据规则(i),首先求出成员自身长度与默认对齐值中的较小者:k = min(sizeof(A.b), 8) = min(4, 8) = 4;A.b在A内的起始地址为k=4的整数倍,所以A.b在A内的起始地址为 k * 2 = 8(因为0 ~ 7已经被A.a占用,所以为k的2倍),A.b存储范围为 8 ~ 11(int占4Byte)。
A.c :根据规则(i),首先求出成员自身长度与默认对齐值中的较小者:k = min(sizeof(A.c), 8) = min(1, 8) = 1;A.c在A内的起始地址为k=1的整数倍,所以A.c在A内的起始地址为 k * 12 = 12(因为0 ~ 11已经被A.a、A.b占用,所以为k的12倍),A.c存储范围为 12(char占1Byte)。
A.d :根据规则(i),首先求出成员自身长度与默认对齐值中的较小者:k = min(sizeof(A.d), 8) = min(2, 8) = 2;A.d在A内的起始地址为k=2的整数倍,所以A.d在A内的起始地址为 k * 7 = 14(因为0 ~ 12已经被A.a、A.b、A.c占用,所以为k的7倍),A.d存储范围为 14 ~ 15(short占2Byte)。ps:地址13因为A.d要对齐,所以被空过去(亦即填充对齐)。
计算A的大小:根据规则(iii),A内成员自身最长长度为 k = sizeof(double) = 8;所以A的长度为 k = 8 的整数倍,sizeof(A) = k * 2 = 16(因为16是A.a、A.b、A.c、A.d能放进A的最小值,所以为k的2倍)。
结构体A内存图解示例:
A: (a代表A.a,b:A.b,c:A.c,d:A.d)
00: a a a a a a a a//00代表左边第一个a的地址为00(一个地址存放1Byte)
08: b b b b c - d d//08代表左边第一个b的地址为08,-表示因为补齐而空掉的地址
根据图解所知,A的大小为16
再来看结构体嵌套的示例
struct B {
int x;
A y; //结构体A嵌套在结构体B内
short z;
};
B.x : 根据规则(i),首先求出成员自身长度与默认对齐值中的较小者:k = min(sizeof(B.x), 8) = min(4, 8) = 4;B.x在B内的起始地址为k=4的整数倍,所以B.x在B内的起始地址为 k * 0 = 0,B.x存储范围为 0 ~ 3(int占4Byte)。
B.y : 根据规则(ii),首先求出结构体A成员的最长长度:k = max(sizeof(A.a), sizeof(A.b), sizeof(A.c), sizeof(A.d)) = max(8, 4, 1, 2) = 8;B.y在B内的起始地址为k=8的整数倍,所以B.y在B内的起始地址为 k * 1 = 8(因为0 ~ 3已经被B.x占用),B.y存储范围为 8 ~ 23(根据前面计算,A占16Byte)。ps:因为内存对齐,所以4 ~ 7被填充对齐了。
B.z:根据规则(i),首先求出成员自身长度与默认对齐值中的较小者:k = min(sizeof(B.z), 8) = min(2, 8) = 2;B.z在B内的起始地址为k=2的整数倍,所以B.z在B内的起始地址为 k * 12 = 24(因为0 ~ 23已经被B.x、B.y占用,所以为k的12倍),B.z存储范围为 24 ~ 25(short占2Byte)。
计算B的大小:根据规则(iii),B内成员自身最长长度为 k = max(sizeof(B.x), sizeof(B.y), sizeof(B.z)) =max(sizeof(B.x), A内成员最长长度, sizeof(B.z)) = max(4, 8, 2) = 8;所以B的长度为 k = 8 的整数倍,sizeof(B) = k * 3 = 32(因为32是B.x、B.y、B.z能放进B的最小值)。
结构体B内存图解示例:
B: (x代表B.x,y:B.y,z:B.z)
00: x x x x - - - -
08: y y y y y y y y
16: y y y y y y y y
24: z z - - - - - -
根据图解所知,B的大小为32。
若是发现错误,欢迎指正。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)