【问题标题】:How to assign an array of structs如何分配结构数组
【发布时间】:2020-01-05 20:49:58
【问题描述】:

我有一个名为 create() 的函数,它返回一个指向名为 ann 的结构的指针,如下所示

typedef struct ann {
    int inputs;                 /* Number of input neurones      */
    int hidden_layers;          /* Number of hidden layers       */
    int hidden;                 /* Number of hidden neurones     */
    int outputs;                /* Number of output neurons.     */
    int weights;                /* Total nof weigths(chromosomes)*/
    int neurons;                /* Total Number of neurones      */
    double *weight;             /* The weights(genotype)         */
    double *output;             /* Output                        */
    double fitness;              /* Total fitness of the network    */
    double *delta;
    actfun activation_hidden;   /* Hidden layer activation func  */
    actfun activation_output;   /* Output layer activation func  */
} ann;

函数create()的原型

ann *create(int inputs, int hidden_layers, int hidden, int outputs);

我需要一个 ann 数组,所以我有以下内容

int population_size = 10;
ann *population = malloc ( population_size * sizeof(ann));

    for( i = 0; i < population_size; i++ ){
        population[i] = create( trainset->num_inputs, 1 , hidden, trainset->num_outputs);
    }

但我收到以下错误

error: incompatible types when assigning to type ‘ann {aka struct ann}’ from type ‘ann * {aka struct ann *}’

我的问题是如何在 population 中对当前元素进行类型转换,以便返回的结构(指针) ann 可以存储在 population 中

这里要求的是函数create()的完整代码

ann *create   ( int inputs, int hidden_layers, int hidden, int outputs ) {

    if (hidden_layers < 0) return 0;
    if (inputs < 1) return 0;
    if (outputs < 1) return 0;
    if (hidden_layers > 0 && hidden < 1) return 0;


    const int hidden_weights = hidden_layers ? (inputs+1) * hidden + (hidden_layers-1) * (hidden+1) * hidden : 0;
    const int output_weights = (hidden_layers ? (hidden+1) : (inputs+1)) * outputs;
    const int total_weights = (hidden_weights + output_weights);

    const int total_neurons = (inputs + hidden * hidden_layers + outputs);

    /* Allocate extra size for weights, outputs, and deltas. */
    const int size = sizeof(ann) + sizeof(double) * (total_weights + total_neurons + (total_neurons - inputs));
    ann *ret = malloc(size);
    if (!ret) return 0;

    ret->inputs = inputs;
    ret->hidden_layers = hidden_layers;
    ret->hidden = hidden;
    ret->outputs = outputs;

    ret->weights = total_weights;
    ret->neurons = total_neurons;

    /* Set pointers. */
    ret->weight = (double*)((char*)ret + sizeof(ann));
    ret->output = ret->weight + ret->weights;
    ret->delta = ret->output + ret->neurons;

    ann_randomize(ret);

    ret->activation_hidden = ann_act_sigmoid_cached;
    ret->activation_output = ann_act_sigmoid_cached;

    ann_init_sigmoid_lookup(ret);

    return ret;
}

【问题讨论】:

  • 不返回指针,返回结构体。
  • 要么这样,要么将其设为指针数组而不是结构数组。
  • @Barmar 怎么做,请帮助我是 c 新手
  • 我支持@Barmar。但是使用指针数组,您将不得不在 create() 中移动动态分配(恕我直言,这更正确)。

标签: c arrays struct


【解决方案1】:

错误

error: incompatible types when assigning to type ‘ann {aka struct ann}’ from type ‘ann * {aka struct ann *}

发生是因为population[i]struct ann,而不是指向它的指针。不同的类型!

正如 Stephan Lechner 的回答所述,您需要做的是更改外部数组(使其成为指针数组)或 create () 函数的返回类型,使其返回结构本身。

我要建议您更改create() 接口,以便将指向它的指针作为参数传递给要填充的输出结构。

在定义了指向ann的指针数组的调用函数中:

ann *population[10] = { 0 };

for( i = 0; i < 10; i++ ){
    if ( create( &population[i], trainset->num_inputs, 1 , hidden, trainset->num_outputs) < 0 ){
        printf ("Issues during creation of ann #%d\n", i);
        break;
    }
} 

// Remember to free the pointers!

没有分配!它被移动到create() 内部,将有两个界面变化:

  1. 输出指针作为参数传递(在我的示例中是第一个)
  2. 返回错误代码(0 表示成功,
int create(ann **outstruct, int inputs, int hidden_layers, int hidden, int outputs){
    int ret = 0;

    ann *tmp = malloc( sizeof(ann));

    // ...
    //do whatever you need to initialize the newly allocated struct

    // set ret to a negative value if anything goes wrong
    // ... but in this case free tmp before returning!
    //...

    outstruct = tmp;

    return ret;
}

在我的示例中,必须将 ann ** 指针传递给 create(),因为它在内部分配了内存。

如果结构是在外部分配的,并且create() 只是填充它的角色,那么一个简单的指针就足够了。

【讨论】:

  • 你是在手机上写的?你怎么敢! :P
  • 我承认。我不得不与自动更正作斗争,但我赢了(除非有什么我忘了更正)。 :)
  • 没有。但它会自动放置空格或大写字母。像If ( p == NULL) 这样的东西。不过没什么特别的。可以办到;只是很慢。请随时就我的回答的技术内容提供反馈。 ;)
  • 您可以禁用这些。如果你愿意,你可以创建一个聊天室。
  • @RobertoCaboni 在智能手机上写出如此详细的答案真的很痛苦。我个人不是 StackExchange Android 应用程序(许多错误等)的忠实粉丝,也不是在智能手机上写作的忠实粉丝。对此深表敬意。
【解决方案2】:

你可以在赋值之前取消引用指针

population[i] = *create(...);

或者您可以更改创建函数的原型以返回结构而不是指向它的指针:

ann create(int inputs, int hidden_layers, int hidden, int outputs);

然而,最好的方法可能是 - 正如 Barmar 所建议的 - 使用指针数组而不是结构对象数组。 一个完整的示例(不能与上面提供的解决方案结合使用)可能如下所示:

ann *create(int inputs, int hidden_layers, int hidden, int outputs) {
   ann* result = malloc (sizeof(ann));
   ..
   return result;
}

...

int population_size = 10;
ann **population = malloc ( population_size * sizeof(ann*));

for( i = 0; i < population_size; i++ ){
    population[i] = create( trainset->num_inputs, 1 , hidden, trainset->num_outputs);
} 

【讨论】:

  • 如果结构的存储空间是由create中的malloc分配的,那么population[i] = *create(...);将导致内存泄漏。
  • @Lxer Lx:分配是population[i] = create(...)
  • 不!在你答案的第二行是population[i] = *create(...);
  • @Lxer Lx:这些解决方案是单独的替代方案,不能混合使用。相应地调整了答案。
  • 如果结构的存储空间是由create() 中的malloc 分配的,则第一种选择将导致内存泄漏,因为malloc 返回的指针被取消引用并永远丢失。在 population[i] = *create(...); 之后如何到达该指针? struct 对象被复制,但指针丢失,在程序终止前不能为free()d。
【解决方案3】:

返回结构的另一种方法是将元素的地址作为参数传递给函数。

ann **population = malloc (sizeof (ann *) * population_size);

for (i = 0; i < population_size; i++) {
    population[i] = malloc (sizeof (ann));
    create (population[i], trainset->num_inputs, 1 , hidden, trainset->num_outputs);
}

然后在函数内部,您可以将值分配给指针。

void create (ann *element, int inputs, int hidden_layers, int hidden, int outputs) {
     element->inputs = inputs;
     ...
}

最后,不要忘记在终止程序之前释放未使用的内存空间。

for (i = 0; i < population_size; i++) {
     free (population[i]);
}
free (population);

【讨论】:

  • 我几乎同时代写了一个非常相似的,即使有一点不同。为了辩护,我是用手机写的。 :)
  • 我喜欢你的想法:>
  • 你的图标看起来像我的...巧合?
  • 我不这么认为,但你的意思是我的看起来像你的?你的看起来像我的:>
【解决方案4】:

从程序逻辑中抽象出来, 您只需要取消引用创建的结果并将其返回值保存给free 函数以防止内存泄漏

ann *create(int inputs, int hidden_layers, int hidden, int outputs);

void foo()
{
int population_size = 10;
ann *population = malloc ( population_size * sizeof(ann));

    for( int i = 0; i < population_size; i++ )
    {
        ann *tempptr;
        population[i] = (tempptr = create( 1, 1 , 1, 1)) ? *tempptr : (ann){0,};
        free(tempptr);
    }
}  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 2020-05-02
    • 1970-01-01
    相关资源
    最近更新 更多