[英]Structure padding in C
我已經閱讀了有關 C 中結構填充的內容: http : //bytes.com/topic/c/answers/543879-what-structure-padding並在文章之后編寫了此代碼,應該打印出“struct pad”的大小像 16 字節,'struct pad2' 的大小應該是 12。-我認為。 我用 gcc 編譯了這段代碼,並進行了不同級別的優化,甚至 sizeof() 運算符都給了我 16 字節。 為什么?
由於 PS3 機器,這些信息對我來說是必要的,其中字節邊界和完整 dma 傳輸的利用很重要:
#include <stdio.h>
#include <stdlib.h>
struct pad
{
char c1; // 1 byte
short s1; // 2 byte
short s2; // 2 byte
char c2; // 1 byte
long l1; // 4 byte
char c3; // 1 byte
};
struct pad2
{
long l1;
short s1;
short s2;
char c1;
char c2;
char c3;
};
int main(void)
{
struct pad P1;
printf("%d\n", sizeof(P1));
struct pad P2;
printf("%d\n", sizeof(P2));
return EXIT_SUCCESS;
}
您的每個結構都包含一個long
,您的平台顯然需要在四字節邊界上。 該結構必須至少與其最對齊的成員對齊,因此它必須是 4 字節對齊的,並且結構的大小必須是其對齊的倍數,以防它進入數組。
需要額外的填充來使long
對齊,因此 4 的最小倍數是 16。
兩點忠告:
您可以通過以下方式計算字段l1
的偏移量
printf("Offset of field %s is %d\\n", "l1", offsetof(struct pad, l1);
要獲得offsetof
宏,您需要#include <stddef.h>
(感謝 caf!)。
如果要盡可能密集地打包數據,請使用unsigned char[4]
代替long
和unsigned char[2]
代替short
,並進行算術轉換。
編輯:: sizeof(struct pad2)
是12。你的代碼有一個錯誤; 結構P2
被聲明為struct pad
類型。 試試這個:
#define xx(T) printf("sizeof(" #T ") == %d\n", sizeof(T))
xx(struct pad);
xx(struct pad2);
PS我絕對應該在午夜之后停止嘗試回答SO問題。
有兩個技巧可以用來解決這個問題
使用指令 #pragma pack(1) 然后 #pragma pack(pop) 示例:
#pragma pack(1) struct tight{ short element_1; int *element_2; }; #pragma pack(pop)
要在編譯期間檢查兩個結構的大小是否相同,請使用此技巧
char voidstr[(sizeof(struct1)==sizeof(struct2)) - 1]; //it will return error at compile time if this fail
在 PS3 上,不要猜測。 使用__attribute__((aligned (16)))
或類似的。 它不僅保證結構的開始將在適當的邊界上對齊(如果是全局的或靜態的),它還可以將結構填充到指定對齊的倍數。
您的代碼沒有顯示您的想法,因為 P1 和 P2 都被定義為 struct pad 的實例。 從未使用過 struct pad2。
如果我將 P2 的定義更改為 struct pad2,gcc 確實決定將其大小設置為 12。
struct pad P1;
printf("%d\n", sizeof(P1));
struct pad P2;
printf("%d\n", sizeof(P2));
P1 和 P2 具有相同類型的“struct pad”,也許您想對 P2 使用“struct pad2”。
所有 CPU 都希望內置數據類型(如(int、float、char、double))存儲在內存中的自然邊界處,在它們的長度地址處。因此,結構填充是為了更快地從內存中訪問數據。 例如,如果聲明了 int,它應該出現在內存中 4 的倍數處,如
int 的大小為 4 字節。
與 double 類似,它以 8 的倍數駐留在內存中。
如果內存正確對齊,CPU 可以運行得更快,工作效率更高。
對於以下示例,讓我們假設:
Sizeof(int)=4 字節
Sizeof(float)=4 字節
Sizeof(char)=1 字節
在BoundsCheck上查找詳細信息
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.