Consider the following code:
#include <stdio.h>
char** baz_alloc(int size)
{
char ** b = malloc((size+1) * sizeof(char*));
for (int i = 0; i < size; i++)
b[i] = "baz";
b[size] = NULL;
return b;
}
void baz_print(char** baz)
{
char** b = baz;
while (*b != NULL)
{
printf("%s\n", *b);
b++;
}
}
void baz_free(char** baz)
{
int len = 0;
char** b = baz;
for (; *b != NULL; len++, b++);
for (int i = 0; i < len; i++)
free(baz[i]);
free(baz);
}
int main()
{
char** baz = baz_alloc(10);
baz_print(baz);
baz_free(baz);
getch();
return 0;
}
The program crashes at the call to the free
function. I've looked at similar example here at SO and it looks pretty much the same. What is wrong in my code?
Thanks.
You're calling free()
on this pointer:
b[i] = "baz"
That pointer wasn't allocated with malloc()
(or calloc()
, realloc()
, etc).
You can't free a string litteral
free(baz[i]);
tries to free from
b[i] = "baz";
As a rule: Only free what you allocated, where you allocated it (in the topmost function causing the allocation), in reverse allocating order.
For example :
int main()
{
char** baz = baz_alloc(10); //'creating' baz
baz_print(baz); //using baz
baz_free(baz); //freeing baz
[...]
}
Is very good practice.
Your baz_free
function only needs to use 1 free
as only 1 malloc
was called in baz_alloc
:
//Allocation
char ** b = malloc((size+1) * sizeof(char*));
//Freeing
free(b); // or in your function free(baz);
If your baz_alloc
function had b[i] = malloc(...)
your baz_free
code would be -almost- correct (You don't need to iterate twice, you could call free(b)
in your first loop).
this loop:
for (int i = 0; i < len; i++)
free(baz[i]);
should not exist because the memory was never allocated.
However the following line:
free(baz);
needs to be there as the initial array of pointers to char was created via a call to malloc().
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.