字節(jié)對齊的原則:
- 數(shù)據(jù)成員對?規(guī)則:結(jié)構(gòu)(struct)(或聯(lián)合(union))的數(shù)據(jù)成員棍厂,第
一個數(shù)據(jù)成員放在offset為0的地方,以后每個數(shù)據(jù)成員存儲的起始位置要
從該成員大小或者成員的子成員大小(只要該成員有子成員,比如說是數(shù)組,
結(jié)構(gòu)體等)的整數(shù)倍開始(比如int為4字節(jié),則要從4的整數(shù)倍地址開始存
儲。- 結(jié)構(gòu)體作為成員:如果一個結(jié)構(gòu)里有某些結(jié)構(gòu)體成員,則結(jié)構(gòu)體成員要從
其內(nèi)部最大元素大小的整數(shù)倍地址開始存儲.(struct a里存有struct b,b
里有char,int ,double等元素,那b應(yīng)該從8的整數(shù)倍開始存儲.)- 收尾工作:結(jié)構(gòu)體的總大小,也就是sizeof的結(jié)果,.必須是其內(nèi)部最大
成員的整數(shù)倍.不足的要補?寺惫。
Struct的字節(jié)對齊
struct的順序存放有一定的規(guī)則
- struct在內(nèi)存中是連續(xù)存放的,利用這點可以對struct進(jìn)行強(qiáng)制轉(zhuǎn)化(只要定義相同即可)蹦疑。
- struct定義的結(jié)構(gòu)體在內(nèi)存中是連續(xù)存放的西雀。所以,數(shù)組結(jié)構(gòu)可以與結(jié)構(gòu)體互相轉(zhuǎn)化歉摧。只需要強(qiáng)制轉(zhuǎn)化一下即可艇肴。但是要注意struct結(jié)構(gòu)體字節(jié)對其的問題,注意不同數(shù)據(jù)類型的定義先后叁温。
案例1:
struct LGStruct1 {
char a; // size:1 , offset:0 , 0 ~ 0 1 (8的倍數(shù)補齊再悼,8)
double b; // size:8 , offset:8 , 8 ~ 15 16
int c; // size:4 , offset:16 , 16 ~ 19 20
short d; // size:2 , offset:20 , 20 ~ 21 22 (8的倍數(shù)補齊,24)
} MyStruct1;
char *a = (void *)&MyStruct1;
double *b = (void *)&MyStruct1.b;
int *c = (void *)&MyStruct1.c;
short *d = (void *)&MyStruct1.d;
/*
查看內(nèi)存情況(iOS 小端存儲)
(lldb) po sizeof(MyStruct1)
24
(lldb) x &MyStruct1
0x100002538: 61 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 3f a..............?
0x100002548: 02 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 ................
(lldb) p &MyStuct1
error: use of undeclared identifier 'MyStuct1'
(lldb) p &MyStruct1
(LGStruct1 *) $1 = 0x0000000100002538
(lldb) p a
(char *) $2 = 0x0000000100002538 "a"
(lldb) p b
(double *) $3 = 0x0000000100002540
(lldb) p c
(int *) $4 = 0x0000000100002548
(lldb) p d
(short *) $5 = 0x000000010000254c
*/
上面的案例很好理解 來個特殊極端的
案例2:
struct LGStruct2 {
double b; // size:8 , offset:0 , 0 ~ 7 8
char a; // size:1 , offset:8 , 8 ~ 8 9 (8的倍數(shù)補齊膝但,8)
int c; // size:4 , offset:12 , 12 ~ 15 20
short d; // size:2 , offset:16 , 16 ~ 17 22 (8的倍數(shù)補齊冲九,24)
} MyStruct2;
struct LGStruct3 {
double b; // size:8 , offset:0 , 0 ~ 7 8
int c; // size:4 , offset:11 , 8 ~ 11 12
char a; // size:1 , offset:12 , 12 ~ 12 13
short d; // size:2 , offset:14 , 14 ~ 15 16
} MyStruct3;
(lldb) p sizeof(MyStruct2)
(unsigned long) $6 = 24
(lldb) p sizeof(MyStruct3)
(unsigned long) $0 = 16
MyStruct3 中的a和d的內(nèi)存分布有點奇怪。
總結(jié)一下:
1跟束、第一個參數(shù) 從offset 0位置開始
2莺奸、第二個參數(shù)開始,以當(dāng)前參數(shù)sizeof的倍數(shù)補齊
3冀宴、最后 以8的倍數(shù)補齊