大小为0的数组如何存储在内存中?

时间:2018-08-28 21:44:41

标签: c arrays pointers memory

如果我只有一个元素的数组,可以说它与指针相同。 但是在内存中如何表示大小为零的数组?

当我声明变量int * table[0]时会发生什么?

3 个答案:

答案 0 :(得分:4)

  

如果我只有一个元素的数组,我们可以说它与a相同   指针

不,我们不能。数组和指针是不同的类型,它们在内部的表示方式也不同。无论数组大小如何,都是如此。现在,在某些情况下(实际上是大多数情况),数组也会衰减为指向其第一个元素的指针。

大小为0的数组按照标准是非法的,但是某些主要的编译器(例如gcc)允许它们作为扩展名。

阅读此问题,以了解数组的内部表示与指针之间的区别:Difference between dereferencing pointer and accessing array elements

答案 1 :(得分:2)

C标准在技术上不支持零长度数组。但是,某些编译器(例如gcc)允许它们作为扩展。

它们是C99之前创建灵活数组成员的方法,如下所示:

typedef struct {
    int len;
    int contents[0];
} arr;

然后,您可以为数组末尾初始化所需的任意空间:

arr* a = malloc(sizeof(*a) + sizeof(a->contents) * 10); /* for a length-10 array */
a->len = 10;

答案 2 :(得分:1)

严格来说,数组的大小不允许为0。这在C standard的6.7.6.2p1节中有规定:

  

除了可选的类型限定符和关键字static之外,[   和]可以分隔表达式或   *。如果它们定界表达式(指定数组的大小),则该表达式应具有整数类型。 如果表达式   是一个常量表达式,其值应大于零。   元素类型不得为不完整或函数类型。的   可选的类型限定符和关键字static将出现   仅在带有数组的函数参数声明中   类型,然后仅在最外层数组类型推导中

某些编译器确实支持此扩展,例如GCC

  

在GNU C中允许声明零长度数组作为扩展。一种   零长度数组可用作结构的最后一个元素   这实际上是一个可变长度对象的标头:

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

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

尽管零长度数组的大小为零,但其中的一个数组成员   这种情况可能会增加封闭类型的尺寸   尾巴填充。零长度数组成员与的偏移量   封闭结构的开头与的​​偏移量相同   具有一个或多个相同类型元素的数组。一个的对齐   零长度数组与其元素的对齐方式相同。