#progma pack(x)說明

一、字節對齊(內存相關)

  現代計算機中內存空間都是按照byte劃分的,從理論上講彷佛對任何類型的變量的訪問能夠從任何地址開始,但實際狀況是在訪問特定變量的時候常常在特定的內存地址訪問,這就須要各種型數據按照必定的規則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。
  各個硬件平臺對存儲空間的處理上有很大的不一樣。一些平臺對某些特定類型的數據只能從某些特定地址開始存取。其餘平臺可能沒有這種狀況,可是最多見的是若是不按照適合其平臺要求對數據存放進行對齊,會在存取效率上帶來損失。好比有些平臺每次讀都是從偶地址開始,若是一個int型(假設爲32位系統)若是存放在偶地址開始的地方,那麼一個讀週期就能夠讀出,而若是存放在奇地址開始的地方,就可能會須要2個讀週期,並對兩次讀出的結果的高低字節進行拼湊才能獲得該int數據。顯然在讀取效率上降低不少。這也是空間和時間的博弈。

二、#pragma pack(x)-結構體對齊規則

  字節對齊:(在 .h 頭文件中爲#pragma pack(x)) (x = 1 2 4 ...)
  結構體中各個成員按照它們被聲明的順序在內存中順序存儲。
  1)將結構體內全部數據成員的長度值相加,記爲sum_a; 
  2)將各數據成員內存對齊,按各自對齊模數而填充的字節數累加到和sum_a上,記爲sum_b。對齊模數是【該數據成員所佔內存】與【#pragma pack指定的數值】中的較小者。
  3)將和sum_b向結構體模數對齊,該模數是【#pragma pack指定的數值】、【未指定#pragma pack時,系統默認的對齊模數8字節】和【結構體內部最大的基本數據類型成員】長度中數值較小者。結構體的長度應該是該模數的整數倍。
以32bit編譯器爲例:
 1 #pragma pack(4)
 2 struct Test1
 3 {
 4     char c;
 5     short sh;
 6     int a;
 7     float f;
 8     int *p;
 9     char *s;
10     double d;
11 };

  總共佔28Bytes。 c的偏移量爲0,佔1個Byte。sh佔2個Byte,它的對齊模數是2(2<4,取小者),存放起始地址應該是2的整數倍,所以c後填充1個空字符,sh的起始地址是2。a佔4個Byte,對齊模數是4,所以接在sh後存放便可,偏移量爲4。f佔4個字節,對齊模數是4,存放地址是4的整數倍,起始地址是8。p,s的起始地址分別是12,16。d佔8個字節,對齊模數是4(4<8),d從偏移地址爲20處存放。存放後結構體佔28個字節,是4的整數倍不用補空字符。spa

相關文章
相關標籤/搜索