【问题标题】:Access data after a header structure在标头结构之后访问数据
【发布时间】:2015-01-28 09:42:22
【问题描述】:

我正在做一些网络编程,我用一些struct 来描述我的帧头:

struct my_frame_header {
    uint16_t field1;
    uint16_t field2;
};

所以,当我有一个缓冲帧时,我可以这样做:

uint8_t buffer[BUFFER_SIZE];
struct my_frame_header *frame_header = (struct my_frame_header *)buffer;

my_read(buffer, BUFFER_SIZE);

我现在可以像这样访问标题字段:

ntohl(frame_header->field1);

现在,我的问题是:在结构之后访问数据最优雅的方式是什么? (即在数据部分的开头获取指针)

【问题讨论】:

  • 这违反了严格的别名规则,不是吗?
  • 谢谢,我不知道this rule。但似乎,通过使用uint8_t buffer[] 就可以了。
  • 我会说是对的,但根本不是。我想如果你在一台 CHAR_BIT > 8 的机器上你会遇到麻烦。但我无法确认,因为我从未在这样的机器上工作过。
  • @Zaibis 不是真的,我在微控制器上运行它,所以应该没问题。感谢您的信息
  • 我担心的是,标准规定只有 charunsigned charsigned char 或同等大小的类型指针允许以这种方式别名。因此,如果您使用的是 16 位机器,则可以通过使用 uint8_t 对其进行别名来打破该规则

标签: c struct network-programming


【解决方案1】:

好吧,如果我正确理解了你的问题,你可以这样做

uint8_t * data = (uint8_t *)buffer + sizeof (struct my_frame)

那么,data 将是指向标头之后的下一个 uint8_t 元素的指针。

【讨论】:

  • 谢谢,我也想过这个解决方案,但对我来说不是很优雅。
【解决方案2】:
uint8_t buffer[BUFFER_SIZE];
struct my_frame_header *frame_header = (struct my_frame_header *)buffer;

这是错误的,buffer 的基地址可以与my_frame_header 不对齐。

关注Memory access and alignment

另一方面:

malloc 给你的块保证是对齐的,这样它 可以保存任何类型的数据。

然后,您可以使用malloc 来跳过此问题:

uint8_t *buffer = malloc(BUFFER_SIZE);

【讨论】:

  • 不是答案,但非常有用。谢谢。正如文章中所建议的,我将添加一些编译器指令来纠正这个问题。
  • 不幸的是,我在一个带有无限循环任务 (freertos) 和堆栈上的数据的微控制器上运行它。所以我真的需要检查一下。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多