【发布时间】:2016-01-14 16:53:04
【问题描述】:
我正在阅读有关 zero-length arrays 的信息,以及它的使用地点和方式以及所有内容。而且我知道当人们想要一个动态大小的成员在一个结构中时使用它们。它与使用指针不同,因为
- 它允许您为结构分配内存,并为结构末尾的可变长度数组分配一个连续的内存块。
- 如果您使用指针,则必须单独分配内存(两次 malloc 调用,可能不连续)或使用其他技巧(以实现正确对齐等)。
取自answer。
现在,这一切都很好。直到我阅读了有关此问题的更多旧事实。
事实 1
- 在 ISO C90 中,您必须将内容的长度设为 1,这意味着要么浪费空间,要么使
malloc的参数复杂化。
事实 2
- GCC 允许将此功能作为扩展。
现在我真的不知道扩展在这里意味着什么。但我在想的是Fact 1。 前面有更多解释。
让我们看一些代码。
#include<stdio.h>
#include<stdlib.h>
struct line
{
int len;
char* content;
};
int main()
{
int i;
struct line* p = malloc(sizeof(struct line) + 10);
p->len = 10;
p->content = (char*)(&(p->len) + 1);
printf("%p\n", &(p->len));
for(i = 0; i < 10; i++)
{
printf("%p\n", &(p->content[i]));
}
}
我想出的这段代码有效地实现了零长度数组的所有功能。可能是多了一行代码,但肯定比Fact 1的坏影响好。
所以,我的问题是,是否有任何特殊原因导致不使用上述方式(在上面的代码中演示)并且他们必须向 GCC 添加扩展,或者使用大小为 1 的数组。
【问题讨论】:
-
零长度数组或 1 个元素的数组确保正确的对齐约束。
-
p->content = (char*)(&(p->len) + 1);应该只是p->content = (char *) (p + 1);以跳过结构。 -
@mikedu95,据我了解,上面的代码也会保证对齐。
-
@Haris 不,您不想要指向自身的指针。它应该指向结构体之后的第一个(对齐的)字节。
-
没有。对于编译器来说,
p->content是一个指针,这意味着它必须取消对它的引用才能获得该值。如果您将该空间用于行的第一个字符,则将使指针无效。如果该字段是一个数组,p->content将只是指向结构内数组的第一个元素的指针。数组不是声明它们的范围内的指针。它们只有在传递给函数时才会衰减为指针。