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

5

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

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


1
如何判断一个只有一个元素的数组大小为零? - Yunnosch
1
注意零长度数组是未定义行为,虽然作为扩展被支持,但这种特定用例似乎没有用处。 - Shafik Yaghmour
只有GCC(和模拟GCC的Clang)允许零大小数组。C标准不允许它们。 - Jonathan Leffler
3个回答

4
如果我有一个只包含一个元素的数组,我们可以说它与指针相同。不,我们不能这样说。无论数组大小如何,数组和指针都是不同类型并且在内部表示上有所不同。现在,在某些情况下(实际上大多数情况下),数组会衰减为指向其第一个元素的指针,这也是真实的。标准规定,大小为0的数组是非法的,但是一些主要的编译器(如gcc)允许它们作为扩展。阅读此问题以查看数组和指针的内部表示之间的差异:Difference between dereferencing pointer and accessing array elements

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
int contents[]; 将是一个灵活的数组成员(FAM)。而 int contents[0]; 则不是 FAM。 - chux - Reinstate Monica
我同意,在这里更多的一致性会更好。经过更多的研究,现在它们更像是历史扩展,已经被灵活数组成员所取代。 - codeandkey

1
严格来说,一个数组不允许大小为0。这在C标准的第6.7.6.2p1节中规定:
“除了可选类型限定符和关键字static之外,[和]可以界定表达式或*。如果它们限定一个表达式(指定一个数组的大小),则该表达式必须具有整数类型。如果表达式是常量表达式,则它必须有大于零的值。元素类型不得是不完整或函数类型。可选类型限定符和关键字static只能出现在带有数组类型的函数参数的声明中,而且只能出现在最外层的数组类型派生中。”
某些编译器支持此作为扩展,例如GCC

Declaring zero-length arrays is allowed in GNU C as an extension. A zero-length array can be useful as the last element of a structure that is really a header for a variable-length object:

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

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

Although the size of a zero-length array is zero, an array member of this kind may increase the size of the enclosing type as a result of tail padding. The offset of a zero-length array member from the beginning of the enclosing structure is the same as the offset of an array with one or more elements of the same type. The alignment of a zero-length array is the same as the alignment of its elements.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接