【问题标题】:Array member of a struct is not assignable结构的数组成员不可分配
【发布时间】:2021-06-25 16:08:56
【问题描述】:

我正在尝试使用 C 来实现 autograd 算法 图数据结构。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>

typedef struct {
    struct variable *var;
    double grad;
} node;

typedef struct {
    double value;
    double grad;
    bool requires_grad;
    node *parents[];
} variable;

variable *init_variable(double value, double grad, bool requires_grad, node *parents) {
    variable *new_variable;
    new_variable->value = value;
    new_variable->grad = grad;
    new_variable->requires_grad = requires_grad;
    new_variable->parents = parents; // Error happens here, "Array type 'node *[]'  is not assignable"
    return new_variable;
}

我不知道如何修复 语言服务提供商。而且我对语言和指针的概念还很陌生,所以请多多包涵。

我该如何解决这个问题?

【问题讨论】:

  • 鉴于variable *new_variable; 是一个指向variable 结构的指针,您认为它指向的是哪个variable 结构?
  • 你确定灵活的数组成员真的是你需要的吗?
  • @SergeyA 你能告诉我如何改进吗?

标签: arrays c pointers


【解决方案1】:

整个数组在 C 中是不可赋值的。此外,您的 variable.parents 是一个灵活的数组成员,这几乎肯定不是您想要的,并且无论如何,相应的指针类型是 node ** 并且您正在尝试为它分配一个node * 类型的对象。

另外,声明...

    variable *new_variable;

... 只声明一个指针,没有任何指向它的东西,也没有分配一个有效的指针值。

我该如何解决这个问题?

这取决于您想要达到的目标。这是一些与您的原始代码相关的有效代码,但我不清楚它是否符合您的要求:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>

typedef struct {
    struct variable *var;
    double grad;
} node;

typedef struct {
    double value;
    double grad;
    bool requires_grad;
    node **parents;     // NOTE: type change
} variable;

variable *init_variable(double value, double grad, bool requires_grad,
        node **parents) {  // NOTE: type change

    // NOTE: dynamic allocation (incurs an obligation to free)
    variable *new_variable = malloc(sizeof *new_variable);

    if (new_variable) {
        new_variable->value = value;
        new_variable->grad = grad;
        new_variable->requires_grad = requires_grad;
        new_variable->parents = parents;  // NOTE: matching types
    }
    return new_variable;  // returns a null pointer if the malloc failed
}

【讨论】:

    【解决方案2】:

    无法分配数组。但是,您可以将 parents 成员的定义更改为具有类型 node * 以匹配参数并使用它。

    typedef struct {
        double value;
        double grad;
        bool requires_grad;
        node *parents;
    } variable;
    

    此外,您在尝试取消引用之前不要初始化 new_variable。这将触发 undefined behavior 并很可能导致崩溃。

    你需要为它分配空间:

    variable *new_variable = malloc(sizeof *new_variable);
    

    【讨论】:

    • node *parents; 可能是错误的。 OP 似乎需要指向节点的指针数组。
    • @SergeyA 鉴于 OP 声称对 C 和指针缺乏经验,我倾向于认为参数类型是正确的,而不是原始成员类型。
    • @dbush,你能指点我完成 init_variable 函数吗?
    • @BrymerMeneses 以上更改应该可以解决问题。
    • @dbush 但 parents 是复数,并且可以预期在一个图中有多个“父母”。我认为,OP 需要一个(动态)数组。
    【解决方案3】:

    对于初学者来说,这个结构定义中的数据成员var

    typedef struct {
        struct variable *var;
        double grad;
    } node;
    

    与此 typedef 中定义的类型 variable 的类型不同。

    typedef struct {
        double value;
        double grad;
        bool requires_grad;
        node *parents[];
    } variable;
    

    在此 typedef 中声明了一个别名为 variable 的未命名结构。 variable 和类型struct variable 是两种不同的类型。

    你应该写

    typedef struct variable {
        double value;
        double grad;
        bool requires_grad;
        node *parents[];
    } variable;
    

    这个结构有一个灵活的数组作为它的数据成员

        node *parents[];
    

    在创建variable 类型的对象时,您需要根据灵活数组的潜在大小为该数据成员单独分配内存。

    在这个函数中

    variable *init_variable(double value, double grad, bool requires_grad, node *parents) {
        variable *new_variable;
        new_variable->value = value;
        new_variable->grad = grad;
        new_variable->requires_grad = requires_grad;
        new_variable->parents = parents; // Error happens here, "Array type 'node *[]'  is not assignable"
        return new_variable;
    }
    

    您正在使用具有不确定值的未初始​​化指针new_variable。因此该函数调用未定义的行为。数组也没有赋值运算符。所以这个说法

    new_variable->parents = parents;
    

    无论如何都是不正确的。

    您需要动态分配variable 类型的对象,并分配所需大小的灵活数据成员parents

    如果你的意思是在结构variable 的定义中是一个标量数据成员而不是灵活数组,那么你需要像这样声明它

    node *parents;
    

    【讨论】:

      猜你喜欢
      • 2011-11-30
      • 2017-06-11
      • 2022-01-02
      • 2012-09-22
      • 2020-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-20
      相关资源
      最近更新 更多