說了N多年都說不清的結構體對齊問題

2021-06-10 07:53:51 字數 2347 閱讀 1028

一 引言

先要明確乙個事情,結構體的對齊規則到底和什麼有關係?. 經過本人」深入的研究和探索」, 答案是, 和編譯器,作業系統, cpu都有關係.

和編譯器有關係相信很多人都不懷疑, 和cpu和作業系統有還關係估計很多人也知道,問題是網上很少看到有人**這個, 這個問題並不是簡單的匯流排長度就可以解釋的清楚的,而且不同的cpu處理機制有很大的不同, 要把每個cpu的機制都講清楚也不是容易的事情. 如果興趣,可以搜一下國外的**,估計有人會講得很明白.

在網上經常可以看類似下面這樣的筆試題目:

struct a

a問題sizeof(a)是多少?

按照上面的說法, 結構體的對齊規則和環境有關係, 那麼這個題是不是有問題呢? 出題者是不是要給出在什麼環境下呢? 我的答案是, 不一定.

因為我覺得至少存在以下兩種可能性:

1 出這個題的公司本身對結構體對齊的問題就不是很了解,隨便在網上找個題,或者在自己的電腦上隨便找個編譯器, 把算出的結果作為標準答案. 他們對這個題的標準答案就是簡單乙個數字(一般是12, 24或16), 僅此而已,沒有任何深入的**.

2 有些公司確實有牛人在, 他們對這個問題理解的很清楚,但是,題目依然是像上面那樣,沒有給出在什麼環境下執行。 他們就是想看一下應聘者對這個問題的認識程度, 如果應聘者的答案僅是乙個數字, 很遺憾, 這一題沒過關(即便可能在大多數環境下都是這個值). 比較好的答案是, 說清楚在什麼環境下的結果是多少,最好還能寫出你的結果是如何算出來的.

如果你面試的時候,碰到上面1情況的公司,勸你還是不要進了,估計做技術不咋的.

so…., 還有乙個結論, 網上很多關於結構體內存對齊的文章, 只要是沒說明環境的,統統都是錯誤的.

二 規則

先說說自己的環境,

x86+xp+visual studio 2005

首先,你要了解在上面這個環境下, 一些基本的資料型別在記憶體中所佔的位元組長度, 這個長度也是它們的對齊模數,  如下:

編譯器本身有乙個預設的對齊模數, 在visual 2005下這個值是8(微軟的編譯器好像都是這個值), 為了方便描述,我把個值叫做」編譯器對齊模數」, 這個東西有什麼用,先不說,先看看如何修改它. 如果你不爽這個預設的對齊模數,可以修改它,方法是用下面這樣的語句:

#pragma pack(n)

n的值就是你想要的對齊模數, 但不是你想指定什麼值都可以, 有兩點要注意:

1 比預設值大的pack將被忽略.比如編譯器預設的對齊模數是8, 你在程式裡加上下面乙個語句:

#pragma pack(20)

這個是沒有意義的,編譯器認為對齊的模數還是8, 比8小的n值才是可以接受的.

2 有效的值只有1, 2, 4, 8, 16,其它值都是無效的

重點要來了, 結構體對齊的規則到底是怎樣的呢? 其實就兩條:

1 結構體中的成員按照某個模數對齊, 這個模數是」編譯器對齊模數」和上述**中自己模數中的較小者

2 按照1的規則算出來的位元組數如果不是」編譯器對齊模數」的倍數,就要補位元組,直到是該模數的倍數.

三 例子

舉個例子, 生動描述一下

#pragma pack(2)

struct s ;

「編譯器對齊模數」是2,

int i點據0~3的位置, short j佔據4~5的位置, double佔據6~13的位置, 一共用了14個位元組, 並且是」 編譯器對齊模數」的倍數, 所以sizeof(s) 的結果是14.

如果注釋掉 #pragma pack(2)這一行, 計算過程如下:

「編譯器對齊模數」是8,

int i點據0~3的位置, short j佔據4~5的位置, 然後6~7補兩個位元組, double佔據8~15的位置, 一共用了16個位元組, 並且是」 編譯器對齊模數」的倍數, 所以sizeof(s) 的結果是16.

下面再給幾個例子, 不給出計算過程,只有答案, 有興趣的可以自己算一下

#pragma pack(2)

struct s ;

結果是10, 如果沒有#pragma pack(2), 結果是16.

#pragma pack(2)

struct s ;

結果是12, 如果沒有#pragma pack(2),結果是12

#pragma pack(2)

struct s ;

結果是18, 如果沒有#pragma pack(2),結果是20

如果是巢狀結構體的情況,即結構體還有結構體,把裡面的結構體展開就可以了.

(僅一家之言, 歡迎拍磚)

原文

無題,都說了,就是無題

身邊的朋友,有訂婚的 有結婚的 有抱娃娃的。自己成了乙個剩男,大家都在為我沒有乙個歸屬而著急上火。經常在自嘲,這個年齡的男人都是準備進入鑽石王老五行列的。更多的時候,都是在迷茫。一直以為自己不會再擁有愛情,不會再為了愛情投入全部的精力 一直以為自己會在30歲的時候,娶乙個普通的女人,平平淡淡度過一生...

雲棲大會上,馬雲和王堅都說了啥?

51cto.com原創稿件 10月13日,雲棲大會回到了阿里的大本營杭州,在經歷過去年2天2萬人的規模後,今年的雲棲大會是重磅公升級,連開4天,預計有4萬人參加,而分論壇數量也達到了數百場。公升級後的雲棲大會,沒有了去年的人山人海,雜亂無序,從大會註冊 安檢到進場,都安排的井井有序,可見阿里雲正在一...

簽到不簽到他們說了不算

多組輸入,先輸入乙個n,代表有n行字串 我比賽的時候根據樣例誤因為該字 符串的長度與n有關 然後判斷由 圍成的最大矩形,在這個矩形中把不為 的全部列印為 為 的列印為 然後輸出圖形。這道題目的基本思想就是先找到那個矩形,我們先將為 的行座標和列座標儲存到兩個陣列,然後對兩個陣列進行排序來確定這個矩形...