Search code examples
arrayscdynamic-memory-allocationdynamic-arraysdynamic-struct

Use an array and allocate memory in a struct (Flexible array members)


So there are 2 structs:

struct Morning { 
    int time;                        
    int day;                 
    struct Morning *next;   //pointer for the next node if there are any collisions     
};

struct Days_Hash_Table {
    int count;                     
    struct Morning **task; // array for the hash table
};

How can I allocate memory for the struct Morning **task? Also, how can I define the array size ?(the size is always stored in a global variable, say array_size.) I tried the following:

struct Days_Hash_Table* table = malloc(sizeof(struct Days_Hash_Table)+ sizeof(struct Morning)*array_size);

and when I tried accessing the array, for example, table->task[0]->time = 0; I got segmentation fault. What is the right way of approaching this? Also will it be easier if I change **task to *task[]?

Thanks!


Solution

  • If you want to allocate the way you show you need to declare it as:

    struct Days_Hash_Table {
        int count;                     
        struct Morning task[]; 
    };
    

    and allocate:

    struct Days_Hash_Table* table = malloc(sizeof(*table)+ sizeof(table -> task[0])*array_size);
    

    EDIT

    struct Morning { 
        int time;                        
        int day;                 
        struct Morning *next;   //pointer for the next node if there are any collisions     
    };
    
    
    struct Days_Hash_Table {
        int count;                     
        struct Morning task[]; 
    };
    
    
    struct Days_Hash_Table*alloc(size_t array_size)
    {
        struct Days_Hash_Table* table = malloc(sizeof(*table)+ sizeof(table -> task[0])*array_size);
    
        if(table)
        {
            for(size_t index = 0; index < array_size; index++)
            {
                table -> task[index].time = index + 1;
                table -> task[index].day = index + 100;
            }
        }
        return table;    
    }
    
    int main(void)
    {
        struct Days_Hash_Table* table = alloc(20);
    
        if(table)
        {
            for(size_t index = 0; index < 20; index++)
            {
                printf("Time[%zu] = %d ", index, table -> task[index].time);
                printf("Day[%zu] = %d\n", index, table -> task[index].day);
            }
        }
        free(table)
    ;}
    

    https://godbolt.org/z/e66vzq