pistacchio pistacchio - 9 months ago 28
C Question

Reallocate array of pointers to char

I have the following code that gives me Segfault when trying to access the array

splitted
. Am I reallocating the array of pointers in a wrong way?

void allocate (char** splitted) {
splitted = malloc(sizeof(char*));
for (int i = 0; i < 3; i++) {
splitted = realloc(splitted, (i + 1) * sizeof(char*));
splitted[i] = "asd";
}
}

int main () {
char** splitted = NULL;
allocate(splitted);
for (int i = 0; i < 3; i++) {
printf("%s", splitted[i]);
}
return 1;
}

Answer Source

Yes, you're reallocating your array in the wrong way - actually several wrong ways.

You're forgetting that splitted is passed by value to the function. So any changes to its value inside the function are invisible to the caller.

So either change the function to add an extra level of indirection.

void allocate (char*** splitted)
{
    *splitted = malloc(sizeof(char*));
    for (int i = 0; i < 3; i++)
    {
        *splitted = realloc(splitted, (i + 1) * sizeof(char*));
        (*splitted)[i] = "asd";
    }
}

/*  to call it in main() */

allocate(&splitted);

or change it to return the new value

char *allocate (char** splitted)
{
    splitted = malloc(sizeof(char*));
    for (int i = 0; i < 3; i++)
    {
         splitted = realloc(splitted, (i + 1) * sizeof(char*));
         splitted[i] = "asd";
    }
    return splitted;
}

/*  to call it in main() */

splitted = allocate(splitted);

Some other notes follow.

I assume you have an #include <stdlib.h> before your code (otherwise the use of malloc() and realloc() would not compile). In future, provide a MCVE, so the people trying to help you don't have to make assumptions or guesses about things you have left out.

The call of malloc() in the function is not needed, since realloc() can accept a NULL.

Also, the realloc() does not need to be in the loop. A single realloc() before the loop will do - just supply the final intended size.

It is highly advisable to CHECK the return values of functions like realloc() and malloc(), since they can both return an error indication. Obviously, if you check the return value, you also need to handle errors sensibly.

Since your code uses malloc()/realloc() to allocate memory, you also need to release it. For example free(splitted) at the end of main(). Yes, modern operating systems clean up - except that not all systems do - so not using free() is a bad habit to acquire. Also, if you ever reuse your code (e.g. rename your main() to something else, and call it from other functions) you will have a memory leak.