Search code examples
clanguage-lawyerflexible-array-member

How to allocate an array of structs with flexible array members comformingly?


I have the following struct with a flexible array member:

struct test {
    size_t sz;
    const char str[];
};

Now I want to allocate some memory to put this struct continuously (like in array). The problem is a declaration like struct test test_arr[] is undefined behavior. 6.7.2.1(p3):

the last member of a structure with more than one named member may have incomplete array type; such a structure (and any union containing, possibly recursively, a member that is such a structure) shall not be a member of a structure or an element of an array.

We know that pointer returned by malloc can be converted to a pointer to any objecut type with fundamental alignment. Consider the following code:

void *obj= malloc(100 * sizeof(struct test)); //enough memory
struct test *t1 = obj;
t1 -> sz = 2;
t1 -> str = {'a', 'b'};
struct test *t2 = (void *) (((char *) obj) + sizeof(struct test) + sizeof(char[2])); // non conforming 

What is the conforming way of doing so?


Solution

  • A struct with a flexible array member can't be a member of an array, as dictated by the quote you gave.

    The best way to handle this is to change the flexible array member to a pointer and allocate space for it separately.

    struct test {
        size_t sz;
        char *str;
    };
    
    ...
    
    struct test *arr = malloc(100 * sizeof(struct test));
    
    arr[0].sz = 2;
    arr[0].str = malloc(2);
    arr[0].str[0] = 'a';
    arr[0].str[1] = 'b';
    
    arr[1].sz = 3;
    arr[1].str = malloc(3);
    arr[1].str[0] = 'c';
    arr[1].str[1] = 'd';
    arr[1].str[2] = 'e';
    

    Also, it's generally not a good idea to have const members of a struct.