0

Given this code :

typedef struct
{
    int len;
    char array[];
} bar_t;
typedef struct {
    int        foo;
    bar_t bar;
} g_data_t;

static g_data_t g_data;
#define LEN 10

static void alloc_bar(bar_t ** bar)
{
    *bar = malloc( sizeof(bar_t) + LEN * sizeof(char) );
    assert(*bar!=NULL);
}
static void assign_bar_some_data(bar_t * bar)
{
    bar->len = LEN;
    memcpy(bar->array, "123456789", bar->len);
}
static void cpy_bar_in_data(g_data_t * data, bar_t * bar)
{
    data->foo = 1234;
    memcpy(&(data->bar), bar, sizeof(bar) + LEN * sizeof(char) ); /* Why don't I need to
                    allocate memory for data->bar when data is a static variable ? */
    free(bar);
}

int main()
{
    g_data_t s_data;
    bar_t *bar1, *bar2;

    alloc_bar(&bar1);
    assign_bar_some_data(bar1);
    cpy_bar_in_data(&g_data, bar1);
    printf("static data: foo=%d : len=%d : array=%s\n", g_data.foo, g_data.bar.len, g_data.bar.array);
    /* Do I need to free g_data.bar before returning ? */

    alloc_bar(&bar2);
    assign_bar_some_data(bar2);
    cpy_bar_in_data(&s_data, bar2);
    printf("stack data: foo=%d : len=%d : array=%s\n", s_data.foo, s_data.bar.len, s_data.bar.array);
    /* How can I can print the correct values whereas I haven't allocated any memory
         for s_data.bar structure ? ( even though we can see below it's crashing thereafter) */

    return 0;
}

Output :

static data: foo=1234 : len=10 : array=123456789                                                                                                                                             
stack data: foo=1234 : len=10 : array=123456789                                                                                                                                              
*** stack smashing detected ***: ./a.out terminated                                                                                                                                          
Aborted

I don't understand how the flexible arrays deal with memory. Moreover, it looks like there is a difference in behavior according to how the structure containing a FAM is declared (static vs stack).

poloDD
  • 71
  • 6
  • In standard C, you have to use dynamic memory allocation to allocate structures with a non-empty FAM. – Jonathan Leffler Jun 18 '20 at 00:33
  • 5
    In `g_data` and `s_data`, the size of the array is 0. Writing anything to the array results in [undefined behavior](https://stackoverflow.com/questions/2397984). Which is to say that even though writing to the `s_data` array appeared to work, it didn't. What it did do is overwrite some critical information on the stack. Writing to `g_data` also only appeared to work. You got away with it because nothing critical was in the memory that got overwritten. – user3386109 Jun 18 '20 at 00:52

0 Answers0