簡體   English   中英

C中的結構填充

[英]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]代替longunsigned 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問題。

有兩個技巧可以用來解決這個問題

  1. 使用指令 #pragma pack(1) 然后 #pragma pack(pop) 示例:

     #pragma pack(1) struct tight{ short element_1; int *element_2; }; #pragma pack(pop)
  2. 要在編譯期間檢查兩個結構的大小是否相同,請使用此技巧

    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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM