關於c++位元組對齊問題
關於c/c++的位元組對齊
這兩天寫解析swf檔案的程式,在結構體指標和從檔案裡讀出來的進行轉換的時候遇到一些問題,就是有乙個struct a,比如:
struct a
char flag;
int length;
int id;
然後乙個飄逸的 struct a *a = (struct a*)buffer; // 世界一下清靜咯
c++的位元組對齊。看到以下這篇文章說的挺清晰的,就轉了過來。
關於c/c++的位元組對齊
近期研究c++的資料型別和資料大小時發現,位元組對齊實際上是乙個c/c++程式猿無法忽視的乙個問題.所以進行了初步的研究.
1.為什麼會出現記憶體對齊問題-從x86 cpu架構說起
相信絕大多數計算機系和軟體學院的學生都學過計算機組成原理這門基礎課程,所以不作入門引導了,沒有相關背景的能夠補補相關課程資料.常有人問我,既然是按位元組定址方式,為何會出現位元組對齊問題呢?難道是記憶體不是連續的嗎?
這個問題實際上和cpu與記憶體的連線方式有關,我們知道cpu會通過位址匯流排address bus與cpu連線用於定址,用data bus資料匯流排連線用於獲取資料,而記憶體一般是ram構成的複雜陣列。
對於這個ram陣列(實際記憶體可能更複雜,可是原理類似), 前16個記憶體位址排列相應記憶體單元關係例如以下:
2.c/c++記憶體對齊的方式
c/c++中的結構/類的成員變數在對齊在記憶體中的排列是與它們擺放的先後順序相關的,先看看以下的結構
1 struct malign_a
2 ;
這個結構的sizeof(malign_a)是多少呢?1+2+1+4 =8?嗎?這個實際上不正確,那麼,怎樣對齊的呢?
因為char是1個byte,所以無論他在什麼位置,都能夠用乙個記憶體週期讀出資料,short是半個字也就是2 bytes,這個時候假如它的位址是某個邊界位置上,那麼,也須要兩個記憶體週期來讀取,以此類推.所以,記憶體對齊就是增加填充padding無意義的資料 來保證某個資料位於乙個能夠通過最少記憶體週期的位置,比方double型僅僅有位址位於%4等於0的位置,才幹保證2個週期讀出.
同一時候對於每乙個詳細平台,不同的編譯器有不同的指定的對齊模式,比方c/c++能夠通過
1 #pragma pack(n) //n為1,2,4,8,16等
來指定對齊.當然,一般x86 32位機器下,都是預設4位元組對齊的.這個n也稱為對齊模數.
對齊策略例如以下:
1.結構體成員對齊:按某成員資料本身大小以及指定大小中較小者對齊
2.結構體總體對齊:按全部成員中最大者和對齊模數中較小者對齊
所以上述結構體按預設對齊方式例如以下:
1.a是char型別,能夠在任何位置,位於位置0
2.b是short型別,2比預設的4小,所以按2位元組對齊,所以在a後面填充1個位元組,b必須位於位置2,佔兩個位元組
3.c是char型別,位於位置4
4.d是int型別,4<=4,所以按4位元組對齊,須要在c後面填充3個位元組,位置為8
5.因為最大成員是4,預設是4,所以結構已經按4對齊,所以總位元組數為12
再把原來的結構體成員位置修改一下:
1 struct malign_b
2 ;
這個結構的大小為8,對齊步驟例如以下:
1.a是char型別,能夠在任何位置,位於位置0
2.c是char型別,位於位置1
3.b是short型別,2比預設的4小,所以按2位元組對齊,這時候恰好位於位置2
4.d是int型別,4 5.因為最大成員是4,預設是4,所以結構已經按4對齊,所以總位元組數為8
最後為了加深理解,我們來看看以下這個結構按對齊模數2對齊時候的memory layout
01 #pragma pack(push)
02 #pragma pack(2)
03 struct malign_b
04 ;
10 #pragma pack(pop)
它的大小為10,當指定為對齊模數2時候
1.因為a是char,1<2,位於位置0
2.因為d是int,4>2,所以按2位元組對齊,所以必須在a後面填充乙個位元組,位於位置2,
3.c是char,位置為6
4.b是short,所以必須在c後面填充乙個位元組,位置為8
5.最大的是4,所以按2對齊,上述結果事實上已經總體是按2對齊,所以總數為10
C 位元組對齊問題
關於c 位元組對齊問題 關於c c 的位元組對齊 這兩天寫解析swf檔案的程式,在結構體指標和從檔案中讀出來的進行轉換的時候遇到一些問題,就是有乙個struct a,例如 struct a char flag int length int id 然後乙個飄逸的 struct a a struct a...
C中位元組對齊問題
好多筆試中,會考結構體的sizeof是多少,這就涉及到了位元組對齊問題。vc或gcc編譯器,預設按4位元組對齊 什麼叫位元組對齊?就是資料在記憶體中存放的方式,它存放的位址需要是它長度的整數倍。比如單位元組放在什麼位址都可以,雙位元組資料只能存放在偶位址上,4位元組數只能存放在是4的倍數的位址上。注...
位元組對齊問題
現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作用和原因 各個硬體平台對儲存空間的...