问题
i have a function called create() that return a pointer to a struct named ann as shown below
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;
prototype of the function create()
ann *create(int inputs, int hidden_layers, int hidden, int outputs);
i need an array of ann s, so i have the following
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);
}
but i am getting the following error
error: incompatible types when assigning to type ‘ann {aka struct ann}’ from type ‘ann * {aka struct ann *}’
My Question is how to type cast the current element in population so that the returned struct (a pointer) ann can be stored in population
As requested here is the full code of the function 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;
}
回答1:
The error
error: incompatible types when assigning to type ‘ann {aka struct ann}’ from type ‘ann * {aka struct ann *}
occurs because population[i] is a struct ann, not a pointer to it. Different types!
What you need to do, as already stated by Stephan Lechner's answer, is either change the array outside (making it an array of pointers) or the returned type of the create () function, making it return the structure itself.
What I'm going to suggest you is a change of create() interface in order to pass a pointer to it as a parameter the output structure to be populated.
In the caller function where the array of pointers to ann is defined:
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!
No allocation! It is moved inside create(), that will have two interface changes:
- The output pointer is passed as a parameter (the first, in my example)
- Returns an error code (0 on success, < 0 on failure)
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;
}
In my example an ann ** pointer had to be passed to create() because it internally allocated the memory.
A simple pointer is enough if the structs are allocated externally and create() has just the role to populate it.
回答2:
You can either dereference the pointer before assigning like
population[i] = *create(...);
or you can change the prototype of your create-function to return a struct instead of a pointer to it:
ann create(int inputs, int hidden_layers, int hidden, int outputs);
The probably best way, however, would be - as suggested by Barmar - to use an array of pointers instead of an array of struct objects. A complete sample - not to be combined with the solutions provided above - could look as follows:
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);
}
回答3:
An alternative to returning structures is to pass the address of the element as a parameter to the function.
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);
}
Then inside the function you can just assign the values to the pointer.
void create (ann *element, int inputs, int hidden_layers, int hidden, int outputs) {
element->inputs = inputs;
...
}
Lastly, don't forget to free up unused memory space before terminating the program.
for (i = 0; i < population_size; i++) {
free (population[i]);
}
free (population);
回答4:
Abstracting from the program logic,
you just need to dereference the result of the create and also save its return value for the free function to prevent the memory leak
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);
}
}
来源:https://stackoverflow.com/questions/59604077/how-to-assign-an-array-of-structs