C90中的可变长度结构

kri*_*rav 3 c gcc c89

GNU C中允许零长度数组,因此可以进行初始化

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

     struct line *thisline = (struct line *)
       malloc (sizeof (struct line) + this_length);
     thisline->length = this_length;
Run Code Online (Sandbox Code Playgroud)

注意:我在这里指的是这个页面:http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html (提供C中可变长度结构的基本介绍)

它继续说:"在ISO C90中,你必须给内容一个长度为1,这意味着你要浪费空间或使参数复杂化为malloc."

那是什么意思?有人可以举例说明如何在C90中初始化变长结构以帮助理解吗?

Sha*_*our 5

如果你真的必须使用c90,那么C FAQ将在问题2.6中涵盖:

struct name {
int namelen;
char namestr[1];
};

struct name *ret =
    malloc(sizeof(struct name)-1 + strlen(newname)+1);
            /* -1 for initial [1]; +1 for \0 */
Run Code Online (Sandbox Code Playgroud)

虽然FAQ确实说:

目前尚不清楚它是合法的还是便携的,但它很受欢迎.该技术的实现可能看起来像这样.

虽然gcc文件基本上说,他们支持它,在C99的常见问题解答说,他们增加了灵活的数组成员,这是我在这个答案覆盖其上覆盖的部分6.7.2.1 结构和联合说明,并具有下面的例子中,它不像C90例如不需要考虑数组大小的特殊数学:

EXAMPLE After the declaration:

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

the structure struct s has a flexible array member d. A typical way to use this
is:

    int m = /* some value */;
    struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));

and assuming that the call to malloc succeeds, the object pointed to by p
behaves, for most purposes, as if p had been declared as:

     struct { int n; double d[m]; } *p;

(there are circumstances in which this equivalence is broken; in particular, the
 offsets of member d might not be the same).
Run Code Online (Sandbox Code Playgroud)