c語言中,基本資料型別與作業系統有關(雖然直接與編譯器相關),基本沒有什麼變化。比如在32位作業系統中,int佔4個位元組,long佔4個位元組,char佔1個位元組,double佔8個位元組。但是結構體的大小並不只與作業系統有關了,與編譯器有比較大的關係。
不同的編譯器有不同的對齊方式,下面以32為linux下gcc4.6為例,分析一下gcc中結構體對齊的問題。
c中可以使用#pragma pack(n)來手動設定對齊數值。gcc預設是4,即按照4位元組對齊。一般有如下的對齊規則:
1、結構體的第乙個資料成員的相對位置為0,後續資料成員按n指定的值和該資料成員自身大小中較小的那個進行對齊。
2、不僅需要資料成員對齊,結構體本身也需要對齊。按照n的值和結構體資料成員中最長的長度中較小的進行對齊。結構體本身對齊即結構體最終的大小須是對齊數值的倍數,且不小於所有資料成員對齊之後的和。
對齊也即意味著資料的相對位址開始值須是對齊數值的倍數。
struct test
i佔4位元組,c佔1位元組,l佔4位元組,d佔8位元組,使用預設對齊數值4。按照第一條規則,對於i,4=n,按4對齊,則i佔據[0,3];對於c,1n,按n=4對齊,則d佔據[12-19]。至此資料成員對齊完畢,佔據了[0-19]共20個位元組。
接著按照規則2進行結構體本身的對齊。結構體資料成員中最大的是d,佔了8個位元組,n預設為4,故按照最小值4進行對齊。12是4的倍數,且最接近資料成員大小之和。故此結構體最終的大小是20。
#pragma pack(n)中n的值之可能是1、2、4。可以用3試一下,編譯器回報錯。如果用8,編譯器不會報錯,但是按照規則計算的大小與實際的大小不一致,因為gcc又按照預設的4進行對齊了,可以測試一下,這裡不再贅述。
n=1,n=2的情況與n=4的情況類似,按照規則對齊即可,略。
結構體位元組對齊小結
1.位元組對齊的原因 一些平台對某些特定型別的資料,只能從特定位址開始訪問。如有些訪問是從偶位址開始,假設int 32位 的資料存在偶位址開始,則只需要乙個週期就能拿到。但如果在奇位址開始,則除了要用2個週期讀取外,還要對高低位址進行拼湊才能得到正確的資料。顯然這是低效的。2.一般編譯器在編譯程式時...
結構體對齊問題
1,比如 structa structb sizeof a 6,sizeof b 8,為什麼?注 sizeof short 2,sizeof long 4 因為 成員對齊有乙個重要的條件,即每個成員按自己的方式對齊.其對齊的規則是,每個成員按其型別的對齊引數 通常是這個型別的大小 和指定對齊引數 這...
結構體對齊問題
昨天華為面試,問到了關於結構體對齊的問題。我懵逼了,結構體對齊是什麼梗?一開始還以為是和資源受限的裝置 微控制器啊之類的嵌入式裝置 開發有關。今天下了下資料,發現原理是真的簡單,當時多考慮一會應該能想出來的。struct struct a 在計算機記憶體中,結構體變數的儲存通常是按字長對齊的,比如8...