C++結(jié)構(gòu)體字節(jié)對齊

雖然內(nèi)存是以自己為單位的,但大部分計(jì)算機(jī)CPU在處理內(nèi)存時(shí),并不會(huì)直接以字節(jié)為單位。處理為了提高讀取速度和減少出錯(cuò)幾率,通常會(huì)以2字節(jié)、4字節(jié)、8字節(jié)、16字節(jié)甚至32字節(jié)為單位來存取內(nèi)存,我們將上述這些存取單位稱為內(nèi)存存取粒度。關(guān)于更詳細(xì)的內(nèi)存對齊原理,這里不做詳細(xì)贅述,可以參考這篇文章內(nèi)存對齊

原文地址快捷方式 -->

有效對齊值

結(jié)構(gòu)體中最大字節(jié)數(shù)成員的長度和對齊模數(shù)中較小的那個(gè)值。具體參照如下表達(dá)式

有效對齊值 = min{ 結(jié)構(gòu)體重最大成員長度, 對齊模數(shù) }

對齊模數(shù):每個(gè)特定平臺(tái)編譯器都有自己默認(rèn)的對齊系數(shù)(也稱對齊模數(shù)),比如GCC中可默認(rèn)對齊模數(shù)是4(#pragma pack(4)),用戶也可以通過預(yù)編譯指令#pragma pack(x)來指定對齊模數(shù),x可以是1、2、4、8、16等來指定這一對齊模數(shù)

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

內(nèi)部對齊(偏移量對齊):結(jié)構(gòu)體第一個(gè)成員的偏移量(offset)為0,以后每個(gè)成員相對于結(jié)構(gòu)體首地址的 offset 都是該成員大小與有效對齊值中較小那個(gè)值的整數(shù)倍,如有需要編譯器會(huì)在成員之間加上填充字節(jié)

偏移量 offset = min { 當(dāng)前成員長度, 有效對齊值 } 的整數(shù)倍

結(jié)構(gòu)體第一個(gè)成員的偏移量offset為0,以后的每一個(gè)成員相對于結(jié)構(gòu)體首地址的offset都是該成員大小與有效對齊值中較小的那個(gè)

外部對齊(結(jié)構(gòu)體整體對齊):結(jié)構(gòu)體的總大小為 有效對齊值 的整數(shù)倍,如有需要編譯器會(huì)在最末一個(gè)成員之后加上填充字節(jié)

結(jié)構(gòu)體的總大小 = 有效對齊值 的整數(shù)倍

實(shí)際案例

以下下案例結(jié)果統(tǒng)一測試方式

int main(int argc, const char * argv[]) {
    NSLog(@"%lu", sizeof(s));
    return 0;
}

案例具體分析

// 默認(rèn)對齊模數(shù):4
struct {
  //4   offset = 0,占4位 [count = 4]
  int x;  
  //1       偏移1的倍數(shù),前4個(gè)字節(jié)(0-1-2-3)被占用,偏移1的倍數(shù)從4開始站一位 offset = 4 [count = 5]
  char y; 
} s;
// 4+1 + (3) = 8
// 默認(rèn)對齊模數(shù):4
struct {
  // 4    offset = 0,占4位 [count = 4]
  int i;   
  // 1    偏移1的倍數(shù),前4個(gè)字節(jié)(0-1-2-3)被占用,偏移1的倍數(shù)從4開始站一位 offset = 4 [count = 5]
  char c1; 
  // 1    偏移1的倍數(shù),前5個(gè)字節(jié)(0-1-2-3)+(4)被占用,偏移1的倍數(shù)從4開始站一位 offset = 5 [count = 6]
  char c2; 
} s;
// 4+1+1 + (2) = 8
// 默認(rèn)對齊模數(shù):4
struct {
  //1 offset = 0,占1位 [count = 1]
  char c1; 
  //4 偏移4的倍數(shù),前1個(gè)字節(jié)(0)被占用,偏移4的倍數(shù)前邊填充(1-2-3),從4開始站一位 offset = 4 [count = 8]
  int i;   
  //1 偏移1的倍數(shù),前8個(gè)字節(jié)(0-1-2-3)+(4-5-6-7)被占用,偏移1的倍數(shù) offset = 8 [count = 9]
  char c2; 
} s;
// 1+(3)+4+1 + (3) = 12
// 有效對齊值:4
struct {
  char c1; // 1     offset = 0,占1位 [count = 1]
  char c2; // 1     offset = 1,占1位 [count = 2]
  int i;   // 4     offset = 4,占1位 [count = 8]
} s;
// 1+ 1 + (2) + 4 = 8

參考文獻(xiàn)

C/C++內(nèi)存對齊詳解

內(nèi)存對齊

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

相關(guān)閱讀更多精彩內(nèi)容

  • 為什么要進(jìn)行內(nèi)存對齊 1.為了cpu讀取更快使CPU的訪問內(nèi)存數(shù)據(jù)的速度加快,如果一個(gè)內(nèi)存的數(shù)據(jù)是經(jīng)過對齊的,那么...
    黑夜no煙絲閱讀 965評論 0 2
  • 想要計(jì)算結(jié)構(gòu)體大小,必須先掌握結(jié)構(gòu)體內(nèi)存對齊規(guī)則: 1.第一個(gè)成員在與結(jié)構(gòu)體變量偏移量為0的地址處。2.其他成員變...
    saygoodbye_e92e閱讀 969評論 1 0
  • 例子 定義兩個(gè)成員個(gè)數(shù)相同(3個(gè)成員)且成員類型相同(int、char、short)的但是成員順序不同的兩個(gè)結(jié)構(gòu)體...
    owl207閱讀 416評論 0 0
  • 原文:https://blog.csdn.net/IT_Quanwudi/article/details/8052...
    介和閱讀 1,587評論 0 0
  • 轉(zhuǎn)載 結(jié)構(gòu)體對齊詳解 結(jié)構(gòu)體數(shù)據(jù)成員對齊的意義 許多實(shí)際的計(jì)算機(jī)系統(tǒng)對基本類型數(shù)據(jù)在內(nèi)存中存放的位置有限制,它們會(huì)...
    erU閱讀 530評論 0 3

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