我需要通过互联网传输数据包,其长度应该是动态的。
struct packet
{
int id;
int filename_len;
char filename[];
};
问题是零长度数组不符合ISO标准。
我应该使用char filename[1];
吗?但是sizeof(struct packet)
将不再返回正确的值。
答案 0 :(得分:6)
我认为你应该看一下动态大小结构的一些现有例子,以获得指导。我所知道的最好的例子是Win32中的TOKEN API。他们使用宏ANYSIZE_ARRAY,它只能解析为1.Raymond Chen做了一篇广泛的博客文章,详细说明了他们为什么这样做了
对于诸如sizeof失败的操作。无论您为动态大小的结构选择何种解决方案,这都将失败。 sizeof是一个编译时操作,您将在运行时重新调整结构大小。它根本无法工作。
答案 1 :(得分:6)
经典问题。您可以简单地处理它(并注意,如果编译器将结构大小向上舍入(我相信)允许的话,sizeof(foo)可能会超过一个),或者您可以执行以下操作:
struct packetheader {
int id;
int filename_len;
};
struct packet {
struct packetheader h;
char filename[1];
};
这很烦人(你必须使用h.id等),但它有效。通常我只是处理它是一个,但上面可能稍微更便携。
答案 2 :(得分:4)
我建议使用char filename[1]
并包含一个终止的0字节。这样,您可以malloc()
正确的结构大小,并避免这样的一次性错误:
ptr = malloc(sizeof(struct packet)+filename_len);
strncpy(&ptr->filename, filename, filename_len);
但接收方必须知道它需要读取filename_len+1
个字节。
答案 3 :(得分:3)
确实zero-length arrays不是标准的一部分。但是你的代码片段中有一个灵活的数组,它是ISO C99标准的一部分。如果您可以使用C99,我会使用灵活的阵列,如果不是jesup的建议可能是最好的。