Reputation: 321
I have a function that gets a char** str_array as such:
char** str_array = Init();
Init allocates an array of char*, which insist contains an array of char.
Then later on I want to free the memory, but I wanted to have a cleanup function, as such:
void FreeStr(char*** arg) {
char** str = *arg;
for (int i = 0; str[i] != '\0'; ++i) {
printf("Str %d: %s\n", i, str[i]);
free(str[i]);
}
free(str);
}
This prints garbage and crashes. The inside of the for loop does work when it is in the same function as where str_array is declared, but not when called as such:
FreeStr(&str_array);
I am confused why this is not working. I thought the extra layer of pointer would make sure I still point to the right memory. What am I misunderstanding please?
Upvotes: 0
Views: 114
Reputation: 223907
There's no need for the extra layer of indirection. Define your function as:
void FreeStr(char** arg)
And call it like this:
FreeStr(str_array);
Also, str[i] != '\0'
is not a good way to test for a null pointer. You should be doing str[i] != NULL
. So your function should look like:
void FreeStr(char** str) {
for (int i = 0; str[i] != NULL; ++i) {
printf("Str %d: %s\n", i, str[i]);
free(str[i]);
}
free(str);
}
Upvotes: 3
Reputation: 530
You haven't specified if Init() returns a fixed length array or it returns a NULL-terminated array. If the latter is the case, which is the usual practice, the correct code would be:
void FreeStr(char*** arg) {
char** str = *arg;
int i;
for (i = 0; str[i] != NULL; ++i) {
printf("Str %d: %s\n", i, str[i]);
free(str[i]);
}
free(str);
*arg = NULL;
}
this way, after calling
FreeStr(&str_array);
provided that str_array is actually a malloc()-allocated NULL-terminated array of malloc()-allocated strings, str_array becomes NULL (you don't want pointers to released memory hanging around, do you?) and all memory is freed.
Upvotes: 4