沒錯,今天2月14,單身狗如我情人節也只能苦逼地擼**了。不知道大家有沒有發現乙個奇怪的現象,見圖~
結構test裡面包含了1個int型變數和2個char型變數,照理說sizeof( struct test )應該等於它們三個相加的結果6才對,為什麼會等於8呢?
事實上,結構成員在記憶體中的儲存並不是想當然地乙個緊挨著乙個排列下來的,由於提高資料讀取速度的要求以及其他一些方面的原因,計算機系統對記憶體中基本資料型別的存放存在一種記憶體對齊機制,即要求這些資料的首位址必須是某個數k(通常為4或8)的整數倍,具體規則如下:
1.編譯器按照結構體成員列表順序給每個成員分配記憶體
2.當成員需要滿足正確的邊界對齊時,成員之間用額外位元組填充
3.結構體的首位址必須滿足結構體中邊界對齊要求最為嚴格的資料型別所要求的首位址
4.結構體的大小為其最寬資料型別的整數倍
知道了這些規則,這個現象就不難理解了,如下圖,int型別的a大小為4位元組,佔據圖中1,2,3,4這四個位元組,char型的b,c長為1位元組,分別佔據5,6兩個位元組位置,為滿足規則4,第7,8兩位被填充進來作為結構體的一部分,因而這個結構體的長度是8個位元組。
現在再來看看下面這種情況!
int型的a被放在了結構體成員列表的第2位,此時結構體的長度變成了12,按上面的規則,a,b,c在記憶體中的排列是下面這種情況:
b是成員列表第1位所以先儲存佔乙個位元組的b,為滿足對齊規則,第2,3,4位用於填充,第5,6,7,8位用來儲存int型的a,第9位儲存c,為滿足規則四,10,11,12位用於填充。(這裡說明一下,計算機記憶體中位址是從0開始的,也就是說上圖中的1,2,3…12實際上應該是0,1,2…11,畫圖時沒注意。。。)
c語言stddef.h標頭檔案中定義了乙個巨集offsetof,可用於得到結構體成員儲存位置相對於結構體首位址的偏移量,可以用來驗證上面的解釋,其原型為:offsetof(type,member),下面我們就來驗證一下~
結果顯示a相對於結構體起始位置的偏移量是4個位元組,符合上面的分析~
下面給大家分享一道我今天碰到的某大公司筆試題~
正確答案是c~~~
整數邊界對齊方式 c中結構體邊界對齊
原則1 普通資料成員對齊規則 第乙個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員大小的整數倍開始 比如int在32位機為 位元組,則要從4的整數倍位址開始儲存 原則2 結構體成員對齊規則 如果乙個結構裡有某些結構體成員,則該結構體成員要從其內部最大元素大小的整數倍位址...
C語言結構體對齊 記憶體對齊問題
c語言結構體對齊也是老生常談的話題了。基本上是面試題的必考題。內容雖然很基礎,但一不小心就會弄錯。寫出乙個struct,然後sizeof,你會不會經常對結果感到奇怪?sizeof的結果往往都比你宣告的變數總長度要大,這是怎麼回事呢?有人給對齊原則做過總結,具體在 看到現在已記不起來,這裡引用一下前人...
字的邊界對齊問題
arm微處理器中支援位元組 半字 字三種資料型別,其中,字需要4位元組對齊 位址的低兩位為0 半字需要2位元組對齊 位址的最低位為0 1 字對齊資料,也就是說每個資料都是用字 32位 來表示的,而arm中的儲存單元都是以位元組為單位,那麼要索引乙個資料,需要連續的4個位元組才行,比如,0x0000 ...