【问题标题】:Aligning at the end of a packed struct在打包结构的末尾对齐
【发布时间】:2017-02-15 16:53:25
【问题描述】:

有没有办法只在打包结构的末尾制作 gcc pad?

我使用压缩结构进行空间优化,但也使用该结构来计算内存偏移量(将多个结构存储在缓冲区中)。因此,如果我的结构的总大小未对齐(比如说不是 4 的倍数),如果我尝试访问缓冲区中的以下结构,我将得到一个 SIGBUS。

例如

sizeof(my_packed_struct) == 11
sizeof(other_struct) == 12

如果我将 my_packed_struct 放在地址 0x2000,我也会将 other_struct 放在 0x200B(+11 字节)。

所以如果我想访问 other_struct,例如(other_struct*)0x200B,我会得到一个 SIGBUS。

所以我很好奇是否有办法让 GCC 填充结构来避免这个问题。

这是定义:

typedef struct __attribute__ ((packed)) my_packed_struct {
    uint8_t att1;
    bool att2;
    uint32_t att3;
    uint32_t att4;
    bool att5;
} my_packed_struct;

我可以添加一个类似的属性

typedef struct __attribute__ ((packed)) my_packed_struct {
    uint8_t att1;
    bool att2;
    uint32_t att3;
    uint32_t att4;
    bool att5;
    uint8_t pad;
} my_packed_struct;

为了确保匹配大小 12,但我正在寻找一种解决方案,我不必手动计算大小和填充(例如,如果我将来必须添加另一个属性)。

我查看了memory alignment within gcc structs,我确实将结构存储在内部缓冲区中,但为了方便和客户使用,我仍然需要公开一个结构。

【问题讨论】:

  • ... for space optimization, 首先:不要使用 bool。并将 bool&char 字段放在相邻的位置,这样它们就只需要对齐一次。
  • 我认为这是针对嵌入式系统的,否则即使您创建了数百万个结构,您也不必只保存几个字节。至于你的问题,other_struct 直接跟在打包结构之后吗?为什么不在打包结构之后将它放在一个对齐良好的地址?然后填充将是两个结构之间的空白空间。
  • 哦,还有一件事,您可能将other_structure 放在0x200B 上,对吧?否则会有重叠。
  • 手动添加pad bye?
  • @Someprogrammerdude 是的,它适用于嵌入式系统,是的,你是对的,它是 0x200B。 other_struct 必须遵循其他结构(基本上是标题/有效负载)。另外,我不想让作者承担调整结构的负担。

标签: c gcc memory-alignment


【解决方案1】:

这个技巧怎么样

union __attribute__ ((packed)) struct_union
{
    struct my_packed_struct data;
    int pad[(sizeof(my_packed_struct)+3)/sizeof(int)];
} struct_union;

并直接使用 struct_union 而不是 my_packed_struct?

为什么它会起作用?

  1. union 已打包,因此不会被额外填充
  2. pad 总是 4 的倍数(因为 int)
  3. sizeof 计算将确保它足够大以容纳整个 my_packed_struct

【讨论】:

  • 你应该把3替换成sizeof(int) - 1(或者任何3的来源)
  • 是 - 3 是 sizeof(int)-1。 int 也可以用其他类型替换 - 但问题是关于 4 字节对齐。
猜你喜欢
  • 2014-07-23
  • 2022-08-15
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
  • 2019-08-07
相关资源
最近更新 更多