Using realloc in recursion
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, me开发者_Python百科m);
.....
}
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.
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
- passing an uninitialized pointer to the function
- any computation done in the function will not alter the variable seen by
main
- freeing that uninitialized pointer once the recursive function returns
So no matter what happens in your code is "undefined behaviour".
精彩评论