ios底層原理:結(jié)構(gòu)體內(nèi)存對(duì)齊原理

內(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ǔ)?。
數(shù)據(jù)類型對(duì)應(yīng)的字節(jié)數(shù)大小

驗(yàn)證對(duì)齊規(guī)則

結(jié)構(gòu)體嵌套成員變量

我們通過(guò)定義兩個(gè)結(jié)構(gòu)體,分別計(jì)算他們的內(nèi)存大小

//1、定義兩個(gè)結(jié)構(gòu)體
struct Mystruct1{
    char a;   //1字節(jié)
    double b; //8字節(jié)
    int c;    //4字節(jié)
    short d;  //2字節(jié)
}Mystruct1;

struct Mystruct2{
    double b;   //8字節(jié)
    int c;      //4字節(jié)
    short d;    //2字節(jié)
    char a;     //1字節(jié)
}Mystruct2;

//計(jì)算 結(jié)構(gòu)體占用的內(nèi)存大小
NSLog(@"%lu-%lu",sizeof(Mystruct1),sizeof(Mystruct2));

輸出結(jié)果如下所示:

我們可以通過(guò)下圖圖來(lái)說(shuō)明下為什么兩個(gè)結(jié)構(gòu)體MyStruct1 & MyStruct2的內(nèi)存大小打印不一致的情況,如圖所示

結(jié)構(gòu)體對(duì)應(yīng)的存儲(chǔ)情況
計(jì)算結(jié)構(gòu)體MyStruct1的大小
  • 變量a:占1個(gè)字節(jié),為第一個(gè)成員變量,因此從0開(kāi)始,此時(shí)min(0,1),即0位置存儲(chǔ)a。
  • 變量b:占8個(gè)字節(jié),從1開(kāi)始計(jì)算,此時(shí)min(1,8),因?yàn)?/8=0不是整數(shù)倍,所以要先偏移到(8,8),即8-15位置存儲(chǔ)b
  • 變量c:占4個(gè)字節(jié),從16開(kāi)始計(jì)算,此時(shí)min(16,4),因?yàn)?6/4=4是整數(shù)倍,所以無(wú)需偏移,即16-19位置存儲(chǔ)c。
  • 變量d:占2個(gè)字節(jié),從20開(kāi)始計(jì)算,此時(shí)min(20,2),因?yàn)?0/2=10是整數(shù)倍,所以無(wú)需偏移,即20-21位置存儲(chǔ)d。

此時(shí)MyStruct1的實(shí)際所需內(nèi)存大小為22個(gè)字節(jié),但因?yàn)?code>結(jié)構(gòu)體的總大小必須是其內(nèi)部最大成員的整數(shù)倍,且MyStruct1中最大成員變量為b占8字節(jié),所以MyStruct1的內(nèi)存大小只能向上取整為8*3=24字節(jié)。

計(jì)算結(jié)構(gòu)體MyStruct2的大小
  • 變量b:占8個(gè)字節(jié),為第一個(gè)成員變量,因此從0開(kāi)始,此時(shí)min(0,8),即0-7位置存儲(chǔ)b
  • 變量c:占4個(gè)字節(jié),從8開(kāi)始計(jì)算,此時(shí)min(8,4),因?yàn)?/8=2是整數(shù)倍,所以無(wú)需偏移,即8-11位置存儲(chǔ)c。
  • 變量d:占2個(gè)字節(jié),從12開(kāi)始計(jì)算,此時(shí)min(12,2),因?yàn)?2/2=6是整數(shù)倍,所以無(wú)需偏移,即12-13位置存儲(chǔ)d
  • 變量a:占1個(gè)字節(jié),從14開(kāi)始計(jì)算,此時(shí)min(14,1),因?yàn)?4/1=14是整數(shù)倍,所以無(wú)需偏移,即14位置存儲(chǔ)a。

此時(shí)MyStruct2的實(shí)際所需內(nèi)存大小為15個(gè)字節(jié),但因?yàn)?code>結(jié)構(gòu)體的總大小必須是其內(nèi)部最大成員的整數(shù)倍,且MyStruct2中最大成員變量為b占8字節(jié),所以MyStruct2的內(nèi)存大小只能向上取整為8*2=16字節(jié)。

結(jié)構(gòu)體嵌套結(jié)構(gòu)體

首先定義一個(gè)結(jié)構(gòu)體MyStruct3,在MyStruct3中嵌套MyStruct2,如下所示

//1、結(jié)構(gòu)體嵌套結(jié)構(gòu)體
struct Mystruct3{
    double b;   //8字節(jié)
    int c;      //4字節(jié)
    short d;    //2字節(jié)
    char a;     //1字節(jié)
    struct Mystruct2 str; 
}Mystruct3;

//2、打印 Mystruct3 的內(nèi)存大小
NSLog(@"Mystruct3內(nèi)存大小:%lu", sizeof(Mystruct3));
NSLog(@"Mystruct3中結(jié)構(gòu)體成員內(nèi)存大?。?lu", sizeof(Mystruct3.str));

輸出結(jié)果如下所示:

計(jì)算結(jié)構(gòu)體MyStruct3的大小
  • 變量b:占8個(gè)字節(jié),為第一個(gè)成員變量,因此從0開(kāi)始,此時(shí)min(0,8),即0-7位置存儲(chǔ)b
  • 變量c:占4個(gè)字節(jié),從8開(kāi)始計(jì)算,此時(shí)min(8,4),因?yàn)?/8=2是整數(shù)倍,所以無(wú)需偏移,即8-11位置存儲(chǔ)c。
  • 變量d:占2個(gè)字節(jié),從12開(kāi)始計(jì)算,此時(shí)min(12,2),因?yàn)?2/2=6是整數(shù)倍,所以無(wú)需偏移,即12-13位置存儲(chǔ)d。
  • 變量a:占1個(gè)字節(jié),從14開(kāi)始計(jì)算,此時(shí)min(14,1),因?yàn)?4/1=14是整數(shù)倍,所以無(wú)需偏移,即14位置存儲(chǔ)a。
  • 結(jié)構(gòu)體成員str:str是一個(gè)結(jié)構(gòu)體,根據(jù)內(nèi)存對(duì)齊原則二,結(jié)構(gòu)體成員要從其內(nèi)部最大成員大小的整數(shù)倍開(kāi)始存儲(chǔ),而MyStruct2中最大的成員大小為8,所以str要從8的整數(shù)倍開(kāi)始,當(dāng)前是從15開(kāi)始,但不符合要求,需要往后移動(dòng)到16,16是8的整數(shù)倍,符合內(nèi)存對(duì)齊原則,即 16-31位置存儲(chǔ) str。

此時(shí)MyStruct3的實(shí)際所需內(nèi)存大小為 32字節(jié),而MyStruct3中最大變量為str,其最大成員內(nèi)存字節(jié)數(shù)為8,所以 MyStruc3 實(shí)際的內(nèi)存大小必須是 8 的整數(shù)倍,32正好是8的整數(shù)倍,所以sizeof(MyStruct3) 的結(jié)果是 32。

其內(nèi)存存儲(chǔ)情況如下所示:

結(jié)構(gòu)體嵌套結(jié)構(gòu)體的內(nèi)存存儲(chǔ)情況
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容