【问题标题】:C: Recommended style for dynamically sized structsC:动态大小结构的推荐样式
【发布时间】:2010-10-28 23:35:17
【问题描述】:

我需要通过互联网传输长度应该是动态的数据包。

struct packet
{
  int id;
  int filename_len;
  char filename[];
};

问题是零长度数组不符合 ISO 标准。

我应该改用char filename[1]; 吗?但随后sizeof(struct packet) 将不再返回正确的值。

【问题讨论】:

    标签: c data-structures struct


    【解决方案1】:

    经典问题。您可以简单地处理它(请注意,如果编译器将结构大小向上舍入,则 sizeof(foo) 可能会超过 1,这是(我相信)允许的),或者您可以执行以下操作:

    struct packetheader {
       int id;
       int filename_len;
    };
    struct packet {
       struct packetheader h;
       char filename[1];
    };
    

    这很烦人(您必须使用 h.id 等),但它确实有效。通常我只是把它当作一个来处理,但上面的可能更便携。

    【讨论】:

      【解决方案2】:

      我认为您应该在此处查看一些现有的动态大小结构示例以获得指导。我所知道的最好的例子是 Win32 中的 TOKEN API。他们使用宏 ANYSIZE_ARRAY,它只解析为 1。Raymond Chen 写了一篇详尽的博客文章,详细说明了他们这样做的原因

      至于sizeof等操作失败。无论您为动态大小的结构选择哪种解决方案,这都会失败。 sizeof 是编译时操作,您将在运行时重新调整结构的大小。它根本行不通。

      【讨论】:

      • sizeof 我的意思是结构的大小,而不是动态字段,因为在接收 UDP 数据包时,我首先读取包含动态字段大小的结构,然后读取动态字段。
      【解决方案3】:

      我建议使用 char filename[1] 并包含一个终止 0 字节。这样,您可以malloc() 正确的结构大小并避免像这样的一次性错误:

      ptr = malloc(sizeof(struct packet)+filename_len);
      strncpy(&ptr->filename, filename, filename_len);
      

      但是接收者必须知道它需要读取filename_len+1字节。

      【讨论】:

        【解决方案4】:

        确实zero-length arrays 不是标准的一部分。但是您的代码 sn-p 中拥有的是一个灵活的数组,它是 ISO C99 标准的一部分。如果您可以使用 C99,我会使用灵活的数组,如果不是,jesup 的建议可能是最好的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-06-27
          • 1970-01-01
          • 1970-01-01
          • 2013-08-20
          • 1970-01-01
          • 2011-10-07
          • 1970-01-01
          相关资源
          最近更新 更多