Initialize nested variable array members

85 Views Asked by At
typedef struct nestedStruct
{
    int a;
    int b;
    char* name;
} nestedStruct;

typedef myStruct
{
    int count;
    nestedStruct myNestedStruct[];
}

I need to define flexible structure which would have number of nested structures in it and structures themselves. And then I need to explicitly initialize them like

myStruct realStruct
{
    2,
    { 1, 2, "name 1" },
    { 3, 4, "name 2" }
} realStruct;

There will be a number of applications using the structure at the width they need.

It is clear for me that this syntax is not correct, I can't find the right one, and this explicitly states it is not possible. Why?

Any suggestions how I can make a "bus" of data structures without separating them into number of pointers to be able to pass single pointer to such struct to the functions and these functions knowing the layout of these bus without additional parameters.

Edit:

this one works

myStruct realStruct
{
    2,
    {
        { 1, 2, "name 1" },
        { 3, 4, "name 2" }
    }
} realStruct;

but there's pedantic warning

warning: initialization of a flexible array member [-Wpedantic]

Well, warnings are there to let me know I may do something incorrectly. Is there a way to tell compiler this is what I actually want to do - without suppressing the warning at all?

Solution:

not that elegant I wanted to, but: replace array with the pointer to array.

typedef myStruct
{
    int count;
    nestedStruct* myNestedStruct;
} myStruct

nestedStruct myList[] =
{
    { 1, 2, "name 1" },
    { 3, 4, "name 2" }
}

myStruct realStruct
{
    2,
    myList
} realStruct;

1

There are 1 best solutions below

0
gulpr On

Flexible array members were invented for dynamic memory allocation.

typedef struct nestedStruct
{
    int a;
    int b;
    char* name;
} nestedStruct;

typedef struct myStruct
{
    size_t count;
    nestedStruct myNestedStruct[];
}myStruct;



myStruct *init(void)
{
    myStruct *str = malloc(sizeof(*str) + 2 * sizeof(str -> myNestedStruct[0]));
    if(str)
    {
        str -> count = 2;
        str -> myNestedStruct[0] = (nestedStruct){ 1, 2, "name 1" };
        str -> myNestedStruct[1] = (nestedStruct){ 3, 4, "name 2" };
    }
    return str;
}

myStruct *init1(size_t size, nestedStruct *initData)
{
    myStruct *str = malloc(sizeof(*str) + size * sizeof(str -> myNestedStruct[0]));
    if(str)
    {
        str -> count = size;
        memcpy(str -> myNestedStruct, initData, size * sizeof(*initData));
    }
    return str;
}

myStruct *add(myStruct *str, nestedStruct *data)
{
    size_t newsize = str ? str -> count + 1 : 1;
    str = realloc(str, sizeof(*str) + newsize * sizeof(str -> myNestedStruct[0]));
    if(str)
    {
        str -> count = newsize;
        str -> myNestedStruct[newsize - 1] = *data;
    }
    return str;
}


int main(void)
{
    myStruct *s1 = init();
    myStruct *s2 = init1(2, (nestedStruct[]){{ 1, 2, "name 1" },{ 3, 4, "name 2" }});

    myStruct *s3 = add(NULL, (nestedStruct[]){{ 1, 2, "name 1" }});
    /* yuo should check if those functions did not return NULL */
    myStruct *tmp = add(s3, &(nestedStruct){ 3, 4, "name 2" });
    if(tmp) s3 = tmp;

    free(s1);
    free(s2);
    free(s3);
}