1

C99 标准允许创建灵活的数组成员,例如

typedef struct pstring {
  size_t length;
  char   string[];
} pstring;

然后用类似的东西初始化它pstring* s = malloc(sizeof(pstring) + len)。是否允许len为零?它看起来是一致的,并且不时节省空间会很好(pstring当然,可能不是这个例子)。另一方面,我不知道下面的代码会做什么:

pstring* s = malloc(sizeof(pstring));
s->string;

这似乎也可能适用于一个编译器而不是另一个编译器,或者在一个操作系统上而不是另一个,或者在某一天而不是另一天,所以我真正想知道的是标准对此有何规定。是malloc在示例代码中未定义的行为,还是只是对s->string无效的访问,还是完全是别的东西?

4

2 回答 2

7

您所做的是有效的,但访问 s->string[0] 或将 s->string 提供给任何访问数据的函数都是无效的。

C99 标准实际上说(§6.7.2.1):

struct s { int n; double d[]; };

...

struct s t1 = { 0 }; // valid

...

赋值t1.d[0]可能是未定义的行为,但也有可能

sizeof (struct s) >= offsetof(struct s, d) + sizeof (double)

在这种情况下,分配将是合法的。然而,它不能出现在严格符合的代码中。

于 2011-02-18T05:05:41.653 回答
1

有一次,Microsoft C 允许以下内容:

struct pstring {
  size_t length;
  char string[0];
};

我用这样的东西来构建一个文本编辑器。然而,这是很久以前的事了,我知道这在当时是不标准的。我什至不能 100% 确定微软仍然支持它。

底线是它取决于您的编译器和当前的编译设置。

于 2011-02-18T04:52:04.787 回答