體系結構的對齊和不對齊,是在時間和空間上的乙個權衡。對齊其中乙個重要的原因是為了提公升cpu的訪問速度,節省了時間。
對於char型資料,其自身對齊值為1,對於short型為2,對於int,float型別,其自身對齊值為4,對於double型,其自身對齊值為8,單位位元組。
一、更改c編譯器的預設位元組對齊方式
在預設情況下,c編譯器為每乙個變數或是資料單元按其自然對界條件分配空間。一般地,可以通過下面的方法來改變預設的對界條件:
· 使用偽指令#pragma pack (n),c編譯器將按照n個位元組對齊。
· 使用偽指令#pragma pack (),取消自定義位元組對齊方式。
另外,還有如下的一種方式:
· __attribute((aligned (n))),讓所作用的結構成員對齊在n位元組自然邊界上。
如果結構中有成員的長度大於n,則按照最大成員的長度來對齊。
· __attribute__ ((packed)),取消結構在編譯過程中的優化對齊,按照實際占用位元組數進行對齊。如:
#pragma pack(8)
typedef struct s1;
typedef struct s2;
#pragma pack()
sizeof(s1) = 2;sizeof(s2) = 6;
二、#pragma pack(n)
每個特定平台上的編譯器都有自己的預設「對齊係數」(也叫對齊模數)。程式設計師可以通過預編譯命令#pragma pack(n),n=1,2,4,8,16來改變這一係數,其中的n就是你要指定的「對齊係數」。
規則:1、資料成員對齊規則:結構(struct)(或聯合(union))的資料成員,第乙個資料成員放在offset為0的地方,以後每個資料成員的對齊按照#pragma pack指定的數值和這個資料成員自身長度中,比較小的那個進行。
2、結構(或聯合)的整體對齊規則:在資料成員完成各自對齊之後,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個進行。
如:#pragma pack(4)
struct node;
struct node n;
printf("%d\n",sizeof(n));
輸出結果為12;
/****************************************轉******************************/
1:資料成員對齊規則:結構(struct)(或聯合(union))的資料成員,第乙個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員大小或者成員的子成員大小(只要該成員有子成員,比如說是陣列,結構體等)的整數倍開始(比如int在32位機為4位元組,則要從4的整數倍位址開始儲存。
2:結構體作為成員:如果乙個結構裡有某些結構體成員,則結構體成員要從其內部最大元素大小的整數倍位址開始儲存.(struct a裡存有struct b,b裡有char,int ,double等元素,那b應該從8的整數倍開始儲存.)
3:收尾工作:結構體的總大小,也就是sizeof的結果,.必須是其內部最大成員的整數倍.不足的要補齊.
等你看完此3條原則,2分鐘已經過去,抓緊時間,實戰3分鐘:
typedef struct bb
bb;typedef struct aa
aa;int main()
{aa a;
cout<
結果是48 24
ok,上面的全看明白了,記憶體對齊基本過關.
再講講#pragma pack().
在**前加一句#pragma pack(1),你會很高興的發現,上面的**輸出為
32 16
bb是4+8+4=16,aa是2+4+8+2+16=32;
這不是理想中的沒有記憶體對齊的世界嗎.沒錯,#pragma pack(1),告訴編譯器,所有的對齊都按照1的整數倍對齊,換句話說就是沒有對齊規則.
明白了不?
那#pragma pack(2)的結果又是多少呢?對不起,5分鐘到了,自己去測試吧.
ps:vc,vs等編譯器預設是#pragma pack(8),所以測試我們的規則會正常;注意gcc預設是#pragma pack(4),並且gcc只支援1,2,4對齊。套用三原則裡計算的對齊值是不能大於#pragma pack指定的n值
還可參考:
成員邊界對齊 pragma pack n
intel 微軟等公司曾經出過一道類似的面試題 1.include 2.pragma pack 8 3.struct example1 4.8.struct example2 9.14.pragma pack 15.int main int argc,char argv 16.問程式的輸入結果是什麼...
pragma pack n 結構體對齊
c語言 開發過程中,其實經常會遇到 pragma pack n pragma pack pragma pack pack,n pragma pack pop,n 等。並且這些語句一般出現在結構體前面。大家都知道這些是進行對齊的,但是關於是怎麼對齊的,總是理解不清晰。以下是我個人總結 什麼是對齊?為什...
pragma pack n 詳解與記憶體對齊
aa a b c 1111 1 11 1 現在去掉第乙個成員變數為如下 pragma pack 4 class testc int nsize sizeof testc 按照正常的填充方式nsize的結果應該是8,為什麼結果顯示nsize為6呢?事實上,很多人對 pragma pack的理解是錯誤的...