零长度数组与指针

时间:2009-03-09 18:02:04

标签: c arrays pointers

编辑:显然其中一些不允许/已经在各种C标准中发生了变化。对于我自己的假设好处,让我们假装我们使用的是gcc test.c而没有标准或警告选项。

特别是我正在研究引擎盖下的细节。我加入了目前的理解。我是对的吗?

char **c1;   //Size for a pointer is allocated on the stack. sizeof(c1) == sizeof(void*)
char *c2[0]; //Nothing is allocated on the stack.  sizeof(c2) == 0

这两种我不知道的情况还有其他区别(除了sizeof)吗?

struct a {
   int i;
   char c[0]; //sizeof(a) is sizeof(int)?  a.c == (&i)+1?
};

据我了解,这通常用于结构末端的可变长度数组。但是呢?

struct b {
   char *c[0] //sizeof(b) is 0?  where does c point?
};

int j;
struct b myb; //myb.c == (&j)+1 == $esp?

此外,如果零指针的空间永远不会分配到任何地方,那么零长度数组的地址如何知道呢?我认为常规数组的地址已知的方式相同,但我现在正在努力绕过它。

5 个答案:

答案 0 :(得分:12)

我唯一一次看到实际使用的零长度数组就是你想要一个可变长度的结构。

如本例中here

所示
    struct line {
       int length;
       char contents[0];
     };

     struct line *thisline = (struct line *)
       malloc (sizeof (struct line) + this_length);
     thisline->length = this_length;

您不希望在上面的结构中使用指针,因为您希望内容成为结构的已分配内存的一部分。

如果在上面的结构上执行sizeof,则不包含任何内容空间。我不确定这是否已成为标准,它会在各种编译器上发出警告。

答案 1 :(得分:9)

ISO C禁止0 - 长度数组。

char **c1;

这定义了一个对象c1,其类型为指向指针的指针。

char *c2[0];

这是编译错误。不允许。不在C中,不在C ++中。

struct a {
  int i;
  char c[0]; //sizeof(a) is sizeof(int)?  a.c == (&i)+1?
};

如前所述的错误 - 数组的大小必须大于零。

 struct a {
  int i;
  char c[1]; 
};

也称为 struct-hack 。几乎所有操作系统都使用低级代码 - Linux,Windows。

C99确实为我们提供了一个无量纲阵列,更好地称为灵活阵列成员:

struct a {
  int i;
  char c[]; /* note: no size */ 
};

答案 2 :(得分:2)

您可以从GCC docs获得一些答案。但这侧重于将零长度数组作为结构的最后成员的主题。它没有给出关于sizeof的直接答案。

(正如其他人所说,零长度数组不在标准C中,但它们在GNU C中。)

答案 3 :(得分:1)

从C99标准(7.20.3)开始,处理分配函数:

  

每个这样的分配都应该产生一个指向与任何其他对象不相交的对象的指针。

     

[...]

     

如果请求的空间大小为零,则行为是实现定义的:       返回空指针,或者行为就像大小一样       非零值,但返回的指针不得用于访问对象。

换句话说,如果在没有初始值设定项的情况下在堆栈上声明b(其中b已将c声明为c[]而不是c[0] }),实际使用的空间b的实际大小将是> 0,因为您无法访问b的任何部分。如果它是通过malloc分配的,则会以0或某些无法访问的唯一值(如果您使用sizeof(b))返回。

答案 4 :(得分:0)

数组的大小不能为零。

ISO 9899:2011 6.7.6.2:

If the expression is a constant expression, it shall have a value greater than zero.

以上文本适用于普通数组(§1)和VLA(§5)。这是C标准中的规范性文本。不允许编译器以不同方式实现它。

gcc -std = c99 -pedantic会对此发出警告。