'Allocating a 2D array in one function and reallocating it in another function?

This is my code:

void allocating(char **word_array)
{
    int i = -1;

    while(i < 20)
    {
        i++;
        printf("%d \n", i);
        word_array[i] = malloc(strlen("hello good sir") + 1);
        strcpy(word_array[i], "hello good sir");
        if (i = 9)
        {
            word_array = realloc(word_array, 20 * sizeof(char *));
        }
    }
}

int main()
{
    char **word_array = malloc(sizeof(char *) * 10);
    
    allocating(word_array);

    free(word_array);
    int i;
    for (i = 0; i < 20; i++)
    {
        printf("%s \n", word_array[i]);
        free(word_array[i]);
    }
}

I'm playing around with dynamic memory allocation and I can't seem to get the code to work. It runs an infinite loop when i = 10 . Is there a problem with allocating the next memory location? Why does it keep printing 10 and not incrementing it?

Thank you!



Solution 1:[1]

This code has multiple problems. First:

if (i = 9)

This is an assignment, not a comparison, so because the value being assigned is non-zero the condition will always be true. You want:

if (i == 9)

Second, you're looping one more iteration than you expect:

    while(i < 20)
    {
        i++;

When i is 19, the condition passes and the loop is entered, then i is immediately incremented to 20 which is past the bounds of the array that's been allocated.

Instead, initialize i to 0 and perform the increment at the end of the loop.

Third, when you do this inside of allocating

word_array = realloc(word_array, 20 * sizeof(char *));

You're modifying a local variable. Changes to it won't be reflected outside of the function. So when the function returns word_array in main will have the same value it had before, and if realloc moved the memory it will no longer be a valid pointer.

The function needs to be changed to take the address of a char **, i.e. a char ***:

void allocating(char ***word_array)
{
    int i = 0;

    while(i < 20)
    {
        printf("%d \n", i);
        (*word_array)[i] = malloc(strlen("hello good sir") + 1);
        strcpy((*word_array)[i], "hello good sir");
        if (i == 9)
        {
            *word_array = realloc(*word_array, 20 * sizeof(char *));
        }
        i++;
    }
}

And the call changed to pass an address:

allocating(&word_array);

Finally, you free(word_array) right after the function returns and subsequenty use word_array. Reading a pointer value after it has been freed is undefined behavior.

Move the call to free after you've finished using the pointer.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1