Eric Ipsum
Eric Ipsum

Reputation: 745

error while initializing int type flexible array in structure in c

i am trying to use flexible array for int variable.

Below is my code:

struct S2 {
    int foo;
    int bar;
    int stud_roll[];
}s2g;

void test(){
        s2g.stud_roll = {0};
}

int main(){
        test();
        return 0;
}

But its not working.

How can fix the problem? what is my error?

Upvotes: 1

Views: 55

Answers (2)

David C. Rankin
David C. Rankin

Reputation: 84541

In order to use your struct with a Flexible Array Member (FAM) you need a pointer to struct, not type struct. The FAM provides the convenience of allowing allocation for the struct and the FAM in a single allocation, rather than needing to allocate for the struct and then for stud_roll separately. For example:

struct S2 {
    int foo;
    int bar;
    int stud_roll[];
} *s2g;   /* note the declaration as a pointer */

void test (void)
{
    s2g = malloc (sizeof *s2g + ELEMENTS * sizeof *s2g->stud_roll);
    if (!s2g) {
        perror ("malloc-s2g");
        exit (EXIT_FAILURE);
    }
    ...

There you allocate storage for both the struct sizeof *s2g plus the element of stud_roll, e.g. ELEMENTS * sizeof *s2g->stud_roll. This provides the single allocation/single free.

A short example would be:

#include <stdio.h>
#include <stdlib.h>

#define ELEMENTS 10

struct S2 {
    int foo;
    int bar;
    int stud_roll[];
} *s2g;

void test (void)
{
    s2g = malloc (sizeof *s2g + ELEMENTS * sizeof *s2g->stud_roll);
    if (!s2g) {
        perror ("malloc-s2g");
        exit (EXIT_FAILURE);
    }

    s2g->foo = 1;
    s2g->bar = 2;

    for (int i = 0; i < ELEMENTS; i++)
        s2g->stud_roll[i] = i + 1;
}

int main (void) {

    test();

    printf ("s2g->foo: %d\ns2g->bar: %d\n", s2g->foo, s2g->bar);
    for (int i = 0; i < ELEMENTS; i++)
        printf (" %d", s2g->stud_roll[i]);
    putchar ('\n');
    free (s2g);

    return 0;
}

(note: since the flexible array member is static, you cannot have an array of struct containing a flexible array member -- but you can have an array of pointers with separate allocation for each)

Example Use/Output

$ ./bin/famtst
s2g->foo: 1
s2g->bar: 2
 1 2 3 4 5 6 7 8 9 10

Upvotes: 3

KamilCuk
KamilCuk

Reputation: 140960

You need to allocate memory for (struct S2).stud_roll. Without any memory you will write out of bounds. Assimung there is no padding sizeof(struct S2) == sizeof(int) + sizeof(int) - there is no memory allocated for stud_roll cause the member takes no memory "by itself".

s2g.stud_roll = {0};

You can't assign arrays in that way in C.

You can use compound literal to allocate some memory on stack:

#define STUD_ROLL_SIZE  4

struct S2 * const s2g = (void*)((char[sizeof(struct S2) + STUD_ROLL_SIZE * sizeof(int)]){ 0 });

void test(void) {
    s2g->stud_roll[0] = 1;
    // or
    memcpy(s2g->stud_roll, (int[]){ 1, 2, 3, 4 }, 4 * sizeof(int));
}

or use malloc to dynamically allocate the memory, you need to allocate more memory than the sizeof(struct S2):

struct S2 *s2g = NULL;

void test(void) {
    s2g = malloc(sizeof(struct S2) + STUD_ROLL_SIZE * sizeof(int));
    if (s2g == NULL) {
        fprintf(stderr, "Abort ship! Abort ship!\n");
        exit(-1);
    }
    s2g->stud_roll[0] = 1;
    free(s2g);
}

Upvotes: 1

Related Questions