簡體   English   中英

C結構填充問題

[英]C structure padding problems

struct something {
    uint32_t a;
    uint8_t  b;
    uint16_t c;
    uint32_t x;
    uint16_t y;
    uint8_t  z;
};

uint8_t *data = malloc(14);
struct something *s = (struct something *)data;

s->a = 1;
s->b = 2;
s->c = 3;
s->x = 4;
s->y = 5;
s->z = 6;

在C中執行此操作是否總是安全的,或者結構填充可能會導致問題?

編輯1(說清楚):是否保證數據[0] ..數據[3] == 1,數據[4] == 2,數據[5] ..數據[6] == 3,數據[ 7] ..數據[10] == 4,數據[11] ..數據[12] == 5和數據[13] == 6?

編輯2:編輯1時出現小錯誤

不是一個安全的操作。 編譯器將以實現定義的方式添加填充。

一般而言,給定大小的成員將在偏移上對齊,該偏移是該大小的倍數。

給定填充的典型方式,此struct很可能是16字節大小。 物理布局很可能(但不一定)看起來像這樣:

struct something {
    uint32_t a;         // offset 0
    uint8_t  b;         // offset 4
                        // 1 byte padding
    uint16_t c;         // offset 6
    uint32_t x;         // offset 8
    uint16_t y;         // offset 12
    uint8_t  z;         // offset 14
    // 1 byte padding
};

不要使用魔術數字。 Intead,使用sizeof運算符。

struct something *s = malloc(sizeof(struct something));

編輯:

如果您希望增加以特定方式布置struct的機會,請參閱本指南以了解結構包裝 如果你遵循這里的做法,那么很有可能(但不是100%)你的struct將按照你期望的方式布局在內存中。

對於GCC,你可以使用__attribute__((packed))上的struct從去除填充struct 但是,這樣做可能會導致性能下降或導致頁面錯誤。 -Wpadded-Wpacked選項還可以告訴您有關填充的更多信息。

硬編碼14 非常頑皮

為什么不使用sizeof(struct something)呢? 這是一個編譯時可計算的常量表達式,因此沒有運行時開銷。

你的預感是正確的:編譯器保留在結構元素之間以及最終元素末尾插入填充的權利。 (請注意,第一個元素的地址必須與struct的地址相同。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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