1

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);
     .....
}
1
  • if(mem) isn't needed: free given a NULL pointer is a no-op. Commented Sep 20, 2011 at 6:15

2 Answers 2

9

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Do not forget to check the result of realloc (it can return NULL). And you should also initialize mem to NULL in main (otherwise the program will crash almost immediately because you're passing an unitialized pointer to realloc).
Your first realloc reallocates from invalid memory.
Bods, I thought you may be talking about something I fixed in the early edits (since it's not in the edit history). Currently, at no stage is either realloc using an invalid pointer.
Hi paxdiablo, thanks for the explanation. However it is not complaining at the free line in main. It is complaining about the realloc function in the recursive function...
That's correct, @Jethro, it's the reallocation which is the problem. You reallocate the block and put the new address into the local (in recurfunc) copy of mem then effectively throw that address away and revert to the old freed block when you return to main (or previous levels of recurfunc).
|
4

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".

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.