C结构填充问题

标签 c struct padding

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(说清楚):是否保证data[0]..data[3]==1,data[4]==2,data[5].. data[6]==3, data[7]..data[10]==4, data[11]..data[12]==5 and data[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
};

不要使用魔数(Magic Number)。相反,使用 sizeof 运算符。

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

编辑:

如果您想增加您的 struct 以特定方式布局的机会,请参阅 guide to structure packing .如果您遵循此处的做法,您的 struct 很有可能(但不是 100%)按照您期望的方式在内存中布局。

对于 gcc,您可以在 struct 上使用 __attribute__((packed)) 来从 struct 中删除填充。然而,这样做可能会导致性能下降或导致页面错误。 -Wpadded-Wpacked 选项还可以告诉您有关填充的更多信息。

关于C结构填充问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41809229/

相关文章:

c++ - C/C++ 应用程序的新手设计注意事项

检查数组是否只包含数字

带 HID 的 C/C++ 接口(interface) - USB 设备

c - C语言无效转换错误

html - 填充导致重叠,流体设计?

套接字accept()后无法获取返回值

c - 在 C 中将 malloc 与结构体和指针一起使用

c++ - 在 C++ 中将定义的结构转换为 double (复数)

css - 固定宽度容器内带边框的图像

html - 更改 Flexbox HTML 中内容的填充