写的很辛苦,都是一字一字敲出来的,希望能帮助到大家。 =TR,~8Z|
如果有不对的地方,欢迎大家交流。 >#+IaKL7
前提条件:确认所有基本数据类型分别占用多少个字节。(这个不完全跟平台一致,不要简单地说8位机,16位机, 32位机, 64机,它还跟编译器本身密切相关) ^4%Zvl
这里就拿32位平台下,并且sizeof(char)=1, sizeof(short)=2, sizeof(int)=4 sizeof(long)=8的情况来说明。(听到32位就理所当然地说是按4字节对齐也是致命的。 ) %}2@rLP
几个注意事项: 3E}EBJLsZ
1. 当前结构体成员本身需要几个字节来储存。(以上都有说明,看成员类型就知道了) !#wd Ve_(
2. 下一个结构成员所需要的空间。(如果下一个成员占用字节较大,当前和往后都按大的字节数来对齐) DaNW~rd{
3. 当前结构体成员当中,占用最多的成员是多少个字节。(这里的“当前结构体”是指从第一个成员到正在分析的那个成员为止的结构体) [fu!AIQs
4. 正在分析的成员按新的对齐来处理后,需要填充的字节是否能够存下一个成员。如果可以,下一个成员有定义和无定义都不会对总占用 - ~O'vLG
字节数产生影响。 ]j>i.5
(在分析结构所占字节数时,请按顺序进行) NV4g~ +n
下面举个例子 S)He$B$pp
typedef struct 6]Q3Yz^h
{ Z?i /r5F
char a; wHz?#MW 3L
short b; nW\(IkX\
int c; F=G{)*Ih
long d; 5p?!ni9
char e; 4X
NxI1w)
}test_t; g.%
请问以上结构体在当前约束条件下,占用多少字节的内存空间? ]O:M$ $
分析: 3L-^<'~-k;
从第一个成员开始: Bz8 &R|~>"
char a;(1) 它占用一个字节, (2)它的下一个成员 short b; 需要占用2个字节 (3) 到short b;为止占用字节最多的是2字节的short b; 好,到此为止,结构会按当前占用字节数最大的成员所占用的字节数来对齐,也就是按2字节对齐,所以char a; short b;一共要占用4个字节 。 rl:KJ\*D
现在开始分析int c; 4yMW^:@
毫无疑问到此为止占8个字节。 b
hjZ7=
同理, long d; 加入后占16字节, 但到此为止,结构体中占字节最多的是8字节的long, 所以后面增加的成员只要是在8字节以内,都得占 1;u4X`8
8字节 ,哪怕char e;只占了一个字节,因为在此之后,要按8字节来对齐了。 Hv#q:R8
所以sizeof(test_t) = 2+2+4+8+8=24字节。 D)='8jV7
]^"k8v/
下面来一题,巩固一下: uK*Nu^
typedef struct eR']#Q46{T
{ KB{RU'?f|
char a; //2 (本来占1字,因为后面的b要2字节对齐,所以要填充一个字节) `ia %)@
short b; //2 (当前占四字节,后面的c也占四字节,刚好对齐,所以不用填充,就占2字节)
1S%k
int c; //4 (后面的d, 只占一个字节, 所以c不用填充, 但往后要按4字节对齐了) 3bC
yTZk
char d //8 (如果没有后面的long e, 它是按4字节对齐至少要占用4字节,但后面来个long e, 需要填充7字节,所以d 要占用8个字节) {I%y;Aab8
long e; //8 bv?0.{Z
char f[9];//16 OKuD"
} test_t; kD~uGA
sizeof(test_t) = 2+2+4+8+8+16=40; exR^/|BR
另外,如果用了#pragam pack(n) //n为 >=0 且为2的较小次方的整数, 或者不写 "5DJu~
那么对齐方式是按设定的来。 n1(?|aJ#1
比如 \Z)1 ?fq
#pragma pack(1) Qqs"?Z,P
typedef struct 5#:pT
{ 1r`i]1<H
char a; q/@dR{-
short b; mAqDjRV1
int c; _[Gb)/@mM
char d; (4~WWU (iT
long e; hsce:TB
char f[9]; /dHs &SU,
} test_t; =7[)'
#pragma pack() 5P^ U_
它按1字节对齐,只占25字节。 sn\;bq
如果上述结构体,指定pack(2)那么它就只占28字节。 <3
@}Lj
}#9(Mul
总结起来就是: 0TE@xqW
1. 当前成员占多少字节 yM$J52#d#
2. 下个成员占多少字节 I/u9RmbU
3. 当前和往后按多少字节对齐 DMgBcP
4. 新的对齐方式下,当前成员填充的字节数够不够容得下下一个成员。 10N,?a
。。。。 go|>o5!g
1. 当前成员占多少字节 tFU;SBt8Ki
2. 下个成员占多少字节 vgPUIxB@
3. 当前和往后按多少字节对齐 :uCdq`SaQl
4. 新的对齐方式下,当前成员填充的字节数够不够容得下下一个成员。 p,#6
@*
。。。。 i&ts YnP2
1. 当前成员占多少字节 i*tv,f.(
2. 下个成员占多少字节 6TFo|z!C
3. 当前和往后按多少字节对齐 z4Oo@3$\R
4. 新的对齐方式下,当前成员填充的字节数够不够容得下下一个成员。 o\4t4}z~'f
这是一个递归的过程,用好它去分析每一个成员就行了。 9 pKm*n&