struct 内存对齐

struct 内存对齐,第1张

对齐规则:
(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。

若是发现错误,欢迎指正。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1498613.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-25
下一篇 2022-06-25

发表评论

登录后才能评论

评论列表(0条)

保存