开发者

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

  1. passing an uninitialized pointer to the function
  2. any computation done in the function will not alter the variable seen by main
  3. freeing that uninitialized pointer once the recursive function returns

So no matter what happens in your code is "undefined behaviour".

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜