探究內(nèi)存對齊

什么是內(nèi)存對齊

現(xiàn)代計算機中內(nèi)存空間都是按照 byte 劃分的,從理論上講似乎對任何類型的變量的訪問可以從任何地址開始,但是實際的計算機系統(tǒng)對基本類型數(shù)據(jù)在內(nèi)存中存放的位置有限制,它們會要求這些數(shù)據(jù)的首地址的值是某個數(shù)k(通常它為4或8)的倍數(shù),這就是所謂的內(nèi)存對齊。

為什么要內(nèi)存對齊呢?

  • 方便快捷
    如果不對齊, 那么就會動態(tài)自適應(yīng)讀取內(nèi)存的長度, 這時候消耗大量性能和時間去計算和適配.
  • 安全
    如果不對齊, 并且沒有自適應(yīng)讀取內(nèi)存, 那么就會出現(xiàn)訪問到其他對象的情況,甚至?xí)霈F(xiàn)訪問到野指針的情況.
    對齊后, 系統(tǒng)只需要固定讀取長度, 以空間換時間來讀取對象的內(nèi)存, 就會大大提高訪問速度以及安全
    注意區(qū)分x86和64位系統(tǒng)所占空間內(nèi)存

內(nèi)存對齊規(guī)則

  • 數(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ù)倍,不足的要補?。
內(nèi)存占用規(guī)則

結(jié)構(gòu)體內(nèi)存計算

struct LGStruct1 {
    double a;   // 大小8  占據(jù)位置(0-7)
    char b;     // 大小1 占據(jù)位置(8) 解析 a在b后邊 起始位置是8 8是1的整數(shù)倍 所以 不需要移位
    int c;      // 大小4 占據(jù)位置(12 13 14 15) b在c后邊 起始位置是9 不是4的整數(shù)倍 需要位置到12的位置
    short d;    // 大小2 占據(jù)位置(16 17) c在d后邊 起始位置是16 是2的整數(shù)倍 不需要移位
}struct1;

// 內(nèi)部需要的大小為: 17
// 最大屬性 : 8
// 結(jié)構(gòu)體整數(shù)倍: 24

struct LGStruct2 {
    double a;   //大小8  占據(jù)位置(0-7)
    int b;      //大小4 占據(jù)位置(8 9 10 11) 解析 a在b后邊 起始位置是8 8是4的整數(shù)倍 所以 不需要移位 
    char c;     //大小1 占據(jù)位置(12) b在c后邊 起始位置是12 不是1的整數(shù)倍 不需要移位 
    short d;    //大小2 占據(jù)位置(14 15) c在d后邊 起始位置是14 是2的整數(shù)倍 不需要移位
}struct2;

// 內(nèi)部需要的大小為: 15
// 最大屬性 : 8
// 結(jié)構(gòu)體整數(shù)倍: 16

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

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