Reputation: 13
Can I do this in C? Valgrind complains that realloc produces an invalid free?
int main(){
void* mem;
// Do stuff
recurfunc(123, mem);
// Do stuff
if(mem)
free(mem);
return 0;
}
void recurfunc(int x, void* mem){
.....
// Do stuff
mem = realloc(mem, newsize);
// Do stuff
recurfunc(x, mem);
.....
}
Upvotes: 1
Views: 1048
Reputation: 881303
Yes, it does indeed complain, because the void *
you're passing in as mem
is a copy of the pointer. Changes to the pointer within the function will not be reflected back to main
.
If you want to change mem
in the function and have it reflected back, you need to pass a pointer to a pointer.
The following code illustrates this:
#include <stdio.h>
#include <stdlib.h>
static void fn (void *p1, void **p2) {
p1 = realloc(p1, 200);
*p2 = realloc (*p2, 200);
printf (" In call: %p %p\n", p1, *p2);
}
int main (void) {
void *x1 = malloc (100);
void *x2 = malloc (100);
printf ("Before call: %p %p\n", x1, x2);
fn (x1, &x2);
printf (" After call: %p %p\n", x1, x2);
return 0;
}
which outputs:
Before call: 0x896f008 0x896f070
In call: 0x896f0d8 0x896f1a8
After call: 0x896f008 0x896f1a8
^
+--- Note this bit.
and you can see that the first value is retained in main
despite it being changed within the function.
Upvotes: 9
Reputation: 114461
Any code that uses
x = realloc(x, size);
is potentially leaking unless also some other variable holds the current value of x
.
The reason is that if reallocation fails the return value is NULL
so the current "unresized" memory block is lost.
In your code moreover you are
main
So no matter what happens in your code is "undefined behaviour".
Upvotes: 4