C:动态大小的结构的推荐样式

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

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

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

我应该使用char filename[1]; 代替? 但是sizeof(struct packet)将不再返回正确的值。

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

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

这很烦人(你必须使用h.id等),但它的工作原理。 通常我只是处理它是一个,但上面可能稍微更便携。

我认为你应该看看动态大小结构的一些现有例子,以获得指导。 我所知道的最好的例子是Win32中的TOKEN API。 他们使用宏ANYSIZE_ARRAY,它只能解析为1. Raymond Chen做了一篇广泛的博客文章,详细说明了他们为什么这样做

至于诸如sizeof失败的操作。 无论您为动态大小的结构选择什么解决方案,这都将失败。 sizeof是一个编译时操作,您将在运行时重新调整结构大小。 它根本无法工作。

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

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

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

实际上, 零长度arrays不是标准的一部分。 但是你的代码片段中有一个灵活的数组,它是ISO C99标准的一部分。 如果您可以使用C99,我会使用灵活的arrays,如果不是jesup的建议可能是最好的。