I'm newbie in programming and learning about struct, when trying to put two flexible array in a single struct they give me a error, why i can't put two array in a single struct? I created a pokemon example to test a array in struct but only *pokemon_name[] works, why?
#include <stdio.h>
void main()
{
struct pokemon
{
int first_generation;
char *pokemon_type[];
char *pokemon_name[];
} number_pokedex[438];
number_pokedex[23].pokemon_name[5] = "Arbok";
number_pokedex[23].pokemon_type[6] = "Poison";
number_pokedex[23].first_generation = 1;
printf("Name of the pokemon: %s\n", number_pokedex[23].pokemon_name[5]);
printf("Type of the pokemon: %s\n", number_pokedex[23].pokemon_type[6]);
printf("From first generation?: %d\n", number_pokedex[23].first_generation);
}
The C standard says in section 6.7.2.1 / 18:
As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member. In most situations, the flexible array member is ignored. In particular, the size of the structure is as if the flexible array member were omitted except that it may have more trailing padding than the omission would imply.
In your case, you have such a flexible array that is not the last element of the struct, and hence the error.
The behavior of a struct with a flexible array, is defined so that it works as if the flexible array starts just after the code of the struct.
+--------------------------------+----+----+----+----+
| struct without flexible array |f[0]|f[1]|f[2]|... |
+--------------------------------+----+----+----+----+
So you can write code such as:
struct test
{
int a;
int flex[];
} *pt, array[10];
static struct test t={ 1, {2,3,4}};
printf ("%x %x %x\n", &t, &t.flex[0], &t.flex[3]);
pt = malloc(sizeof(struct test)+20*sizeof(int));
printf ("%x %x\n", pt, &pt->flex[0]);
The problem is that you have to know how many elements are reserved for the flexible array (either statically reserved or dynamically allocated). If C would allow several flexible arrays, this kind of behavior would no longer be possible, since the compiler would not know where the second flexible array would start.
Now you can very well rewrite your code by using more robust fixed size arrays, or using dynamic arrays by the means of a pointer to pointers.
struct pokemon
{
int first_generation;
char **pokemon_type;
char **pokemon_name;
} number_pokedex[438];
In this case, you'd have to inialize the char**
pointers by allocating an array of sufficient size:
// assuming that no more than 10 elements in item 23.
number_pokedex[23].pokemon_name = calloc (10, sizeof(char*));
number_pokedex[23].pokemon_type = calloc (10, sizeof(char*));
You'd also need to free the arrays when no longer needed. Finally you'd have to take extra care when copying struct elements, since you'd clone the pointers.