每個特定平台的
編譯器都有乙個預設的
對齊係數,
gcc中是4,
vc中貌似是
8。也可以通過於
編譯命令
#pragma pack(n)
來指定該
係數,其中n的
值經測試
只能是1,2
和4.對齊規則:1
、結構體的第乙個資料成
員放在相對位置
為0的地方,以後
每個資料成員按
#pragma pack(n)中n
指定的值和該
資料成員自身長
度中比較
小的那個進行
對齊。2、資料成員完成
對齊後,
結構體本身也要
對齊,按照
#pragma pack(n)中n
的值和結
構體資料成員中最
長的長度中
較小的進行
對齊。驗證(
環境:gcc 4.4;sizeof(char)=1;sizeof(int)=4;sizeof(short)=2;sizeof(long)=4;sizeof(long long)=8):1
、預設情況(n=4
)struct st1 ; 整個
結構體成
員對齊後所佔的區
間為[0,8],佔12
個位元組,接著結
構體本身
對齊,成員中最
長的是4,
n也等於
4,所以
結構體本身按4對齊
(即對齊
係數)。整個結
構體的大小
= 比整個
結構體資料成
員所佔的總空
間大或相等且和
對齊係數求模結果
為0、與之距離最近的數。
本例中,
12%4=0
,所以結
構體st1佔12
個位元組的空間
。2、#pragma pack(1)(
即n=1)
struct st1 ; 整個
結構體成
員對齊後所佔的區
間為[0,8],佔9
個位元組,接著結
構體本身
對齊,成員中最
長的是4,
n等於1,所以
結構體本身按1對齊
(即對齊
係數)。整個結
構體的大小
= 比整個
結構體資料成
員所佔的總空
間大或相等且和
對齊係數求模結果
為0、與之距離最近的數。
本例中,
9%1=0
,所以結
構體st1佔9
個位元組的空間
。3、#pragma pack(2)(
即n=2)
struct st1 ; 整個
結構體成
員對齊後所佔的區
間為[0,8],佔9
個位元組,接著結
構體本身
對齊,成員中最
長的是4,
n等於2,所以
結構體本身按2對齊
(即對齊
係數)。整個結
構體的大小
= 比整個
結構體資料成
員所佔的總空
間大或相等且和
對齊係數求模結果
為0、與之距離最近的數。
本例中,
10%2=0
,所以結
構體st1佔10
個位元組的空間
。為什麼說
#pragma pack(n)中n
只能是1,2
,4呢?比如
3,如果
n=3,在編譯
的時候會警告「
對齊邊界必須是
2 的較小次方,而不是
3」,也就是
說是不起作用的,按默
認對齊係數對齊。
再如8,會有什
麼結果?看下一例:4、
#pragma pack(8)(
即n=8)
struct siz ; 如果
8起作用,分析一下:
struct siz ; 整個
結構體成
員對齊後所佔的區
間為[0,23],佔24
個位元組,接著結
構體本身
對齊,成員中最
長的是8,
n等於8,所以
結構體本身按8對齊
(即對齊
係數)。
24%8=0,
所以佔24個位元組
。然而,很不幸,執行的結果是
20.
接下來,用預設的
對齊係數
4來分析一下:
struct siz ; 整個
結構體成
員對齊後所佔的區
間為[0,19],佔20
個位元組,接著結
構體本身
對齊,成員中最
長的是8,
n等於4,所以
結構體本身按4對齊
(即對齊
係數)。
20%4=0,
所以佔20個位元組
。與執行
結果一致。
綜上分析,當
n=8的時候
gcc仍然使用的是預設的
對齊係數4.
記憶體對齊問題
一直困惑自己有兩個問題 1.程式為什麼要做記憶體對齊?1.處理器訪問記憶體是粒度為多位元組時,如果資料不是在邊界處,則,處理器需要分多個時鐘週期進行資料的訪問。2.增加可移植性。並非所有的處理器都可以訪問任何位址,可能出現硬體錯誤。具體可以參考 2.struct中如何計算記憶體對齊?先說說c語言中s...
記憶體對齊問題
首先由乙個程式引入話題 1 環境 vc6 windows sp22 程式13 include iostream 45 using namespace std 67 struct st1 8 1314 struct st215 20 21int main 2227 程式的輸出結果為 sizeof st...
記憶體對齊問題
一 什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作...