內(nèi)存對齊

目錄

  • 內(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末漾抬,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子常遂,更是在濱河造成了極大的恐慌纳令,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烈钞,死亡現(xiàn)場離奇詭異泊碑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)毯欣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來臭脓,“玉大人酗钞,你說我怎么就攤上這事。” “怎么了砚作?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵窘奏,是天一觀的道長。 經(jīng)常有香客問我葫录,道長着裹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任米同,我火速辦了婚禮骇扇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘面粮。我一直安慰自己少孝,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布熬苍。 她就那樣靜靜地躺著稍走,像睡著了一般。 火紅的嫁衣襯著肌膚如雪柴底。 梳的紋絲不亂的頭發(fā)上婿脸,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機(jī)與錄音柄驻,去河邊找鬼狐树。 笑死,一個胖子當(dāng)著我的面吹牛凿歼,可吹牛的內(nèi)容都是我干的褪迟。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼答憔,長吁一口氣:“原來是場噩夢啊……” “哼味赃!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起虐拓,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤心俗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蓉驹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體城榛,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年态兴,在試婚紗的時候發(fā)現(xiàn)自己被綠了狠持。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡瞻润,死狀恐怖喘垂,靈堂內(nèi)的尸體忽然破棺而出甜刻,到底是詐尸還是另有隱情,我是刑警寧澤正勒,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布得院,位于F島的核電站,受9級特大地震影響章贞,放射性物質(zhì)發(fā)生泄漏祥绞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一鸭限、第九天 我趴在偏房一處隱蔽的房頂上張望蜕径。 院中可真熱鬧,春花似錦里覆、人聲如沸丧荐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽虹统。三九已至,卻和暖如春隧甚,著一層夾襖步出監(jiān)牢的瞬間车荔,已是汗流浹背在辆。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工芽突, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人急灭。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓帽借,卻偏偏與公主長得像珠增,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子砍艾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容