Search code examples
cstructsegmentation-faultmallocdynamic-arrays

How to correctly allocate memory to a dynamic array of integers stored in a struct?


I have a function that sets values to a struct:

My struct:

struct entry {
    char key[MAX_KEY];
    int* values;
    size_t length;
    entry* next;
    entry* prev;
};

My function:

// Sets entry values
void command_set(char **commands, int arg_num) {
    struct entry e;
    e.length++;
    strcpy(e.key, commands[1]);
    for (int i = 2; i < arg_num; i++) {
        e.values[i - 2] = atoi(commands[i]);
    }
}

where:

  • **commands: is a array of strings
  • arg_num: is how many strings are in the array
  • key: is the name of the entry
  • values: are integer values store in the entry

I run the code and I get a segmentation fault 11. I have narrowed it down to the line:

e.values[i -2] = atoi(commands[i]);

I assume that I have to use malloc to allocate memory as I don't appear to have gone out of bounds with my loop. I have tried to understand the correct way to allocate memory however I can't seem to get the syntax correct for allocating sizeof(int) to a dynamic array of integers.

I have tried:

e.values[i - 2] = malloc(sizeof(int));

and

e.values[i - 2] = (int) malloc(sizeof(int));

and

e.values[i - 2] = malloc(sizeof(int *));

However I get the error:

incompatible pointer to integer conversion assigning
  to 'int' from 'void *' [-Werror,-Wint-conversion]

Solution

  • You must allocate the whole array:

    e.values = malloc(sizeof(int) * (arg_num - 2))
    

    Important: Remember to call free when you're done with the memory or you will have a memory leak.


    You have another problem though, unrelated to the one you're asking about.

    You do

    struct entry e;
    e.length++;
    

    When the structure object e is defined, it is uninitialized, all its members will have an indeterminate value. Using such uninitialized data in any way except to initialize it will lead to undefined behavior. And you do use such uninitialized values when you do e.length++.

    That increase simply doesn't make any sense in the code as you show it. On the other hand, that function doesn't make a lot of sense anyway since the variable e and all its data will simply "disappear" when the function returns. So I can only assume that it's not the complete function you show us.

    To initialize the structure to all zeroes, simply do

    struct entry e = { 0 };