结构内部的灵活阵列成员(c99)

结构内部的灵活阵列成员(c99),c,arrays,c99,C,Arrays,C99,我使用这段代码已经有一段时间了,它工作得很好,但是实现它让我有些头疼。它使用灵活的数组成员(FAM)又名结构黑客。既然C99有可能使用可变长度数组(VLA),我想知道如何在这一部分中发挥优势 typedef struct nO { int oper; /* some operator */ int nops; /* number of args */ struct nO *ptn[1]; /* expansibl

我使用这段代码已经有一段时间了,它工作得很好,但是实现它让我有些头疼。它使用灵活的数组成员(FAM)又名结构黑客。既然C99有可能使用可变长度数组(VLA),我想知道如何在这一部分中发挥优势

typedef struct nO
{
    int oper;              /* some operator */
    int nops;              /* number of args */
    struct nO *ptn[1];     /* expansible array <=== HERE */
} nodoOper;

nodoOper *operator(int o, int n, ...)
{
    va_list ap;
    nodoOper *tn;
    size_t tam;
    int i;

    tam = sizeof(nodoOper) + (n - 1) * sizeof(nodoOper *); /* <=== AND HERE */

    if((tn=malloc(tam))==NULL)
        yyerror("Memory fault (cod. 4)");

    tn->oper = o;
    tn->nops = n;
    va_start(ap, n);
    for(i=0; i<n; i++)
        tn->ptn[i] = va_arg(ap, nodoOper*);
    va_end(ap);
    return tn;
}
我看到的第一个问题是,我返回一个指向局部变量的指针。但除此之外,这条路是否富有成效?
谢谢

事实上,您想在这里使用的不是可变长度数组,而是
struct
hack,又名“不完整类型”,又名“灵活数组成员”:


(哦,这些东西叫做数组,而不是矩阵。)

这种结构的
C
名称是“flexible array member”(它可能有助于您的搜索),或C99之前的“struct hack”

请参阅本手册中的6.7.2.1;文本中有示例用法



您可能还对“可变长度数组”感兴趣。参见标准中的6.7.5.2。

“哦,这些东西叫做数组,而不是矩阵”--哈哈:)好的!我会更正邮件的。正如@pmg所说,这个名字对于帮助网络搜索很重要。谢谢larsmans,但它仍然需要malloc。我的意图是彻底消灭马洛克。还有其他选择吗?@Beco博士:不,你不能用这种方式摆脱malloc。如果你真的使用VLA,你可以去掉
malloc
,但在
struct
@larsman中这行不通,
tam
的大小应该是malloced吗?这有点错误
sizeof(nodoOper)+n*sizeof(struct nO*)
或者更好的
offsetof(nodoOper,ptn)+n*sizeof(struct nO*)
或者更好的是
max
的真正正确公式和
sizeof(nodoOper)
。我可能在编辑时犯了错误。我认为现在正确的方法是可变长度数组。在“
struct
hack”下的索引中也列出了:)显然这不是灵活数组成员的情况。我认为您有一个FAM,@DrBeco。拉斯曼答案中的例子应该让你很容易开始。很抱歉有这么多版本。我已编辑完问题标题。我在为一些我甚至不知道名字的事情寻求帮助。再一次抱歉,伙计们。现在我知道Flexible Array Member(FAM)是Struct Hack的同义词,而且这已经是我所做的事情了,我很清楚,这个问题的目的是想找到另一种方法来使用另一种工具C99 gaves,我们称之为可变长度数组(VLA)。如果这不可能,那么。。。好的,我们保留已经实施的旧方法。如果你决定保留“旧方式”,你可以考虑使用<代码> OffStand(Nodooper-PTN)+N*siZeof(Nodoope*)< /Cord>来计算大小。这样你就不需要记住减去
1
。这样,您根本不依赖于数组声明中
[]
之间指定的内容。
struct nOp
{
    int oper;             /* some operator */
    int nops;             /* number of args */
    struct nOp *ptn[n];   /* Variable Length Array (VLA) */
};
struct nOp tnop;
struct nOp *tn2;

tn2 = &tnop;
return tn2;
typedef struct nO
{
    int oper;
    int nops;
    struct nO *ptn[];  // <== look ma, no index!
} nodoOper;

// skip a bit
// no more (n-1) --------\
tam = sizeof(nodoOper) + n * sizeof(nodoOper *);
void foo(int size)
{
    float a[size];               // run-time stack allocation
    printf("%lu\n", sizeof(a));  // and run-time sizeof (yuck)
}