目錄
- 內(nèi)存對齊規(guī)則
- 對齊系數(shù)
- 面試題演練
一、內(nèi)存對齊規(guī)則 (關(guān)于面試題中結(jié)構(gòu)體內(nèi)存對齊計(jì)算總結(jié))
- 1.1、數(shù)據(jù)成員對齊規(guī)則
結(jié)構(gòu)(struct)(或聯(lián)合(union))的數(shù)據(jù)成員,第一個數(shù)據(jù)成員放在offset(偏移)為0的地方褐墅,以后每個數(shù)據(jù)成員的對齊按照 #pragma pack 指定的數(shù)值和這個數(shù)據(jù)成員自身長度中,比較小的那個進(jìn)行
- 1.2、結(jié)構(gòu)(或聯(lián)合)的整體對齊規(guī)則
在數(shù)據(jù)成員完成各自對齊之后胸完,結(jié)構(gòu)(或聯(lián)合)本身也要進(jìn)行對齊,對齊將按照 #pragma pack 指定的數(shù)值和結(jié)構(gòu)(或聯(lián)合)最大數(shù)據(jù)成員長度中翘贮,比較小的那個進(jìn)行赊窥。
1.3:結(jié)構(gòu)體作為成員:
如果一個結(jié)構(gòu)里有某些結(jié)構(gòu)體成員,則結(jié)構(gòu)體成員要從其內(nèi)部最大元素大小的整數(shù)倍地址開始存儲狸页。
二锨能、#pragma pack(n) 對齊系數(shù)
????????每個特定平臺上的編譯器都有自己的默認(rèn)“對齊系數(shù)”(也叫對齊模數(shù))。程序員可以通過預(yù)編譯命令#pragma pack(n),n=1,2,4,8,16來改變這一系數(shù)址遇,其中的n就是你要指定的“對齊系數(shù)”熄阻。
????????其中,Xcode 中默認(rèn)為#pragma pack(8)
三傲隶、演練
演練1饺律、
struct StructOne {
長度 對齊 偏移 區(qū)間
char a; 1 < 8 1 0 [0]
double b; 8 = 8 8 8 [8, 15]
int c; 4 < 8 4 16 [16, 19]
short d; 2 < 8 2 20 [20, 21]
} MyStruct1;
解讀:
1、數(shù)據(jù)成員的對齊按照#pragma pack-8和自身長度中比較小的那個進(jìn)行
-- char a 的自身長度為 1, 1 < 8, 按 1 對齊
2跺株、第一個數(shù)據(jù)成員放在offset為0的地方
-- char a 的偏移為 1
3复濒、整體對齊系數(shù) = min((max(int,short,char,double), 8) = 8,
將 21 提升到 8 的倍數(shù)乒省,則為 24巧颈,所以最終結(jié)果為 24 個字節(jié)
整體對齊系數(shù) = min((max(int,short,char,double), 8) = 8,將21提升到8的倍數(shù)袖扛,則為24砸泛,所以最終結(jié)果為24個字節(jié)
演練2、
struct StructOne {
長度 對齊 偏移 區(qū)間
double b; 8 = 8 8 0 [0, 7]
char a; 1 < 8 1 8 [8]
short d; 2 < 8 2 10 [10, 11]
int c; 4 < 8 4 12 [12, 15]
} MyStruct1;
解讀:
這個和演練1不同的是short d蛆封,由于它是 2 對齊唇礁,上一個偏移量為 9,
9不是2的整數(shù)倍,所以向上取整惨篱,到10盏筐,"short b" 偏移為10
留給大家自己算的
struct x_ {
char a; // 1 byte
int b; // 4 bytes
short c; // 2 bytes
char d; // 1 byte
} MyStruct1;
struct y_ {
int b; // 4 bytes
char a; // 1 byte
char d; // 1 byte
short c; // 2 bytes
} MyStruct2;
NSLog(@"%lu,%lu", sizeof(MyStruct1), sizeof(MyStruct2));
12---8
struct StructOne {
char a; // 1字節(jié)
double b; // 8字節(jié)
int c; // 4字節(jié)
short d; // 2字節(jié)
} MyStruct1;
struct StructTwo {
double b; // 8字節(jié)
char a; // 1字節(jié)
short d; // 2字節(jié)
int c; // 4字節(jié)
} MyStruct2;
NSLog(@"%lu---%lu--", sizeof(MyStruct1), sizeof(MyStruct2));
2019-01-16 08:52:13.830861+0800 size[1031:10969] 24---16--
復(fù)雜一點(diǎn)演練(結(jié)構(gòu)體包含結(jié)構(gòu)體-明天解讀)
struct EE
{ 長度 對齊 偏移 區(qū)間
int a; 4 < 8 4 0 [0, 3]
char b; 1 < 8 1 4 [4]
short c; 2 < 8 2 6 [6, 7]
//結(jié)構(gòu)體內(nèi)部最大元素為int ,由于偏移量為8剛好是4的整數(shù)倍,所以從8開始存放接下來的struct FF
struct FF
{
int a1; 4 < 8 4 8 [8, 11]
char b1; 1 < 8 1 12 [12]
short c1; 2 < 8 2 14 [14, 15]
char d1; 1 < 8 1 16 [16]
};
// 整體對齊:min(max(int, char, short), 8) = 4, 將內(nèi)存大小由17補(bǔ)齊到4的整數(shù)倍20
char d; 1 < 8 1 21 [21]
// 整體對齊系數(shù) = min((max(int,short,char), 8) = 4砸讳,將內(nèi)存大小由21補(bǔ)齊到4的整數(shù)倍24
};
----24
struct B { 長度 對齊 偏移 區(qū)間
char e[2]; 1 < 8 2 0 [0, 1]
short h; 2 < 8 2 2 [2, 3]
//結(jié)構(gòu)體內(nèi)部最大元素為double ,由于偏移量為8剛好是4的整數(shù)倍琢融,所以從8開始存放接下來的struct A
struct A {
int a; 4 < 8 4 8 [8, 11]
double b; 8 = 8 8 16 [16, 23]
float c; 4 < 8 4 24 [24, 27]
};
// 整體對齊系數(shù) = min((max(int,double ,float), 8) = 8
// 將內(nèi)存大小由28補(bǔ)齊到8的整數(shù)倍32,∴ result = 32
};
----32
參考文章:
iOS 關(guān)于面試題中結(jié)構(gòu)體內(nèi)存對齊簿寂、類內(nèi)存對齊計(jì)算總結(jié)
http://www.reibang.com/p/a371e2613ec8
http://www.reibang.com/p/3294668e2d8c