pragma pack n 詳解與記憶體對齊

2021-04-27 19:39:44 字數 1607 閱讀 9265

aa       a      b     c

1111   1*    11   1***

現在去掉第乙個成員變數為如下**:

#pragma pack(4)

class testc

;int nsize = sizeof(testc);

按照正常的填充方式nsize的結果應該是8,為什麼結果顯示nsize為6呢?

事實上,很多人對#pragma pack的理解是錯誤的。

#pragma pack規定的對齊長度,實際使用的規則是:

結構,聯合,或者類的資料成員,第乙個放在偏移為0的地方,以後每個資料成員的對齊,按照#pragma pack指定的數值和這個資料成員自身長度中,比較小的那個進行。

也就是說,當#pragma pack的值等於或超過所有資料成員長度的時候,這個值的大小將不產生任何效果。

而結構整體的對齊,則按照結構體中最大的資料成員 和 #pragma pack指定值 之間,較小的那個進行。

#pragma pack(2)

class testb

;具體對其如下:

aa       a      b      c

1111   1*    11    1*

sizeof(testb)是10。

現在去掉第乙個成員變數為如下**:

#pragma pack(4)

class testc

;a      b     c

1*    11  1*

整個類的大小是5位元組,按照min(sizeof(short),4)位元組對齊,也就是2位元組對齊,結果是6

所以sizeof(testc)是6。

感謝 michael 提出疑問,在此補充:

當資料定義中出現__declspec( align() )時,指定型別的對齊長度還要用自身長度和這裡指定的數值比較,然後取其中較大的。最終類/結構的對齊長度也需要和這個數值比較,然後取其中較大的。

可以這樣理解,

__declspec( align() ) 和 #pragma pack是一對兄弟,前者規定了對齊的最小值,後者規定了對齊的最大值,兩者同時出現時,前者擁有更高的優先順序。

__declspec( align() ) 的乙個特點是,它僅僅規定了資料對齊的位置,而沒有規定資料實際占用的記憶體長度,當指定的資料被放置在確定的位置之後,其後的資料填充仍然是按 照#pragma pack規定的方式填充的,這時候類/結構的實際大小和記憶體格局的規則是這樣的:

在 __declspec( align() )之前,資料按照#pragma pack規定的方式填充,如前所述。當遇到__declspec( align() )的時候,首先尋找距離當前偏移向後最近的對齊點(滿足對齊長度為 max(資料自身長度,指定值) ),然後把被指定的資料型別從這個點開始填充,其後的資料型別從它的後面開始,仍然按照#pragma pack填充,直到遇到下乙個__declspec( align() )。

當所有資料填充完畢,把結構的整體對齊數值和__declspec( align() )規定的值做比較,取其中較大的作為整個結構的對齊長度。

特別的,當__declspec( align() )指定的數值比對應型別長度小的時候,這個指定不起作用。

pragma pack n 對齊用法詳解

什麼是對齊,以及為什麼要對齊 現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作用和原因 各...

Pragma Pack n 與記憶體分配

pragma pack n 解釋一 每個特定平台上的編譯器都有自己的預設 對齊係數 也叫對齊模數 程式設計師可以通過預編譯命令 pragma pack n n 1,2,4,8,16來改變這一係數,其中的n就是你要指定的 對齊係數 規則 1 資料成員對齊規則 結構 struct 或聯合 union 的...

Pragma Pack n 與記憶體分配

pragma pack n n 位元組的對齊方式 vc 對結構的儲存的特殊處理確實提高 cpu 儲存變數的速度,但是有時候也帶來 了一些麻煩,我們也遮蔽掉變數預設的對齊方式,自己可以設定變數的對齊方式。vc 中提供了 pragma pack n 來設定變數以 n 位元組對齊方式。n 位元組對齊就是說...