這里我們來(lái)分析結(jié)構(gòu)體內(nèi)存對(duì)齊方式, 從中我們可以間接的分析出在OC中內(nèi)存的對(duì)齊方式大概什么樣.
進(jìn)行分析前我們要先知道不同類(lèi)型的屬性, 所對(duì)應(yīng)的內(nèi)存空間是什么. 如下:
| C | OC | 32位 | 64位 |
|---|---|---|---|
| bool | BOOL(64位) | 1 | 1 |
| signed char | (__signed char)int8_t BOOL(32位) | 1 | 1 |
| unsigned char | Boolean | 1 | 1 |
| short | int16_t | 2 | 2 |
| unsigned short | unichar | 2 | 2 |
| int int32_t | NSInteger(32位) boolean_t(32位) | 4 | 4 |
| unsigned int | boolean_t(64位) NSInteger(32位) | 4 | 4 |
| long | NSInteger(64位) | 4 | 8 |
| unsigned long | NSInteger(64位) | 4 | 8 |
| long long | int64_t | 8 | 8 |
| float | CGFloat(32位) | 4 | 4 |
| double | CGFloat(64位) | 8 | 8 |
內(nèi)存對(duì)齊的原則
- 數(shù)據(jù)成員對(duì)齊規(guī)則: 結(jié)構(gòu)(struct)(或聯(lián)合(union))的數(shù)據(jù)成員, 第一個(gè)數(shù)據(jù)成員放在offset為0的地方, 以后每個(gè)數(shù)據(jù)成員存儲(chǔ)的起始位置要從該成員大小或者成員的子成員大小(只要該成員有子成員, 比如說(shuō)是數(shù)組, 結(jié)構(gòu)體等)的整數(shù)倍開(kāi)始(比如int為4字節(jié), 則要從4的整數(shù)倍地址開(kāi)始存儲(chǔ)).
- 結(jié)構(gòu)體作為成員: 如果一個(gè)結(jié)構(gòu)里有某些結(jié)構(gòu)體成員, 則結(jié)構(gòu)體成員要從其內(nèi)部最大元素大小的整數(shù)倍地址開(kāi)始存儲(chǔ). (struct a里存有struct b, b里有char, int, double等元素, 那b應(yīng)該從8的整數(shù)倍開(kāi)始存儲(chǔ).)
- 收尾工作: 結(jié)構(gòu)體的總大小, 也就是sizeof的結(jié)果, 必須是其內(nèi)部最大成員的整數(shù)倍, 不足的要補(bǔ)齊.
例子
struct LGStruct1 {
double a; // 8 (0-7)
char b; // 1 [8 1] (8)
int c; // 4 [9 4] 9 10 11 (12 13 14 15)
short d; // 2 [16 2] (16 17)
}struct1;
// 內(nèi)部需要的大小為: 17
// 最大屬性 : 8
// 結(jié)構(gòu)體整數(shù)倍: 24
struct LGStruct2 {
double a; //8 (0-7)
int b; //4 (8 9 10 11)
char c; //1 (12)
short d; //2 13 (14 15) - 16
}struct2;
// 內(nèi)部需要的大小為: 16
// 最大屬性 : 8
// 結(jié)構(gòu)體整數(shù)倍: 16
擴(kuò)展結(jié)構(gòu)體中有其他結(jié)構(gòu)體
接上面代碼分析:
struct LGStruct2 {
double a; //8 (0-7)
int b; //4 (8 9 10 11)
char c; //1 (12)
short d; //2 13 (14 15) - 16
struct LGStruct1 e; // 這個(gè)需要17在例子1中以及分析很清晰了, 16 + 17 從17 ~ 33
}struct2;
// 內(nèi)部需要的大小為: 33
// 最大屬性 : 8
// 結(jié)構(gòu)體整數(shù)倍: 40
struct LGStruct2 {
double a; //8 (0-7)
int b; //4 (8 9 10 11)
struct LGStruct1 e; //16 + 17 = 34 從8的整數(shù)倍16開(kāi)始
char c; //1 (40) 從40開(kāi)始
short d; //2 41 42 - 42
}struct2;
// 內(nèi)部需要的大小為: 42
// 最大屬性 : 8
// 結(jié)構(gòu)體整數(shù)倍: 48