stressed_geek
stressed_geek

Reputation: 2176

Is it required to free a pointer variable before using realloc?

Is it necessary to free memory before using realloc again for a pointer variable. Which of the following is correct?

for(i = 0; i < n; i++){
   myArray = (int *)realloc(myArray, i*sizeof(int));
}

for(i = 0; i < n; i++){
   myArray = (int *)realloc(myArray, i*sizeof(int));
   free(myArray);
   myArray = NULL;
}

Upvotes: 7

Views: 6101

Answers (4)

pb2q
pb2q

Reputation: 59607

The specific usefulness of realloc is that you don't need to free before using it: it exists to grow memory that has already been allocated.

So it is not required and would be uncommon. When passed a NULL pointer, realloc behaves as malloc. If you're using free before calling it, you might as well be using malloc.

Neither example is correct since you've omitted error handling. All the allocators can return NULL and the usage of realloc is a little tricky in this respect. Read the docs and examples carefully. Specifically, ptr = realloc(ptr, ... is always a bad idea because if realloc fails and returns NULL, then you've just lost your reference and leaked memory. Instead use a tmp variable, e.g.:

tmp = realloc(ptr, newSize);
if (tmp != NULL)
    ptr = tmp;
else handle_error();

Upvotes: 16

cdhowie
cdhowie

Reputation: 168958

This depends on what you want to do. realloc() specifically is designed to take an existing allocation and change its size, preserving as much data as possible. Both examples you have provided are correct in the sense that they will compile, but they will do different things.

realloc(NULL, n) is the same as malloc(n), so the second case is semantically equivalent to:

for(i = 0; i < n; i++){
   myArray = (int *)malloc(i*sizeof(int));
   free(myArray);
   myArray = NULL;
}

In the first example, the data pointed to by myArray will be retained. In the second example, the existing allocation will be thrown away and replaced with a brand new, uninitialized allocation. Any data pointed to by the original allocation will be discarded.


It should be noted that realloc() will return NULL if the allocation fails -- but if you passed it a non-NULL pointer then that allocation will not have been freed. Passing one pointer into realloc() and assigning the result directly into that same pointer variable can cause a memory leak if the reallocation fails, because the original allocation will still exist. The correct way to do this is to use a temporary pointer variable.

Upvotes: 4

user529758
user529758

Reputation:

Neither one. You should always check for realloc returning NULL; if you don't, you'll be leaking memory if it does. Also, you're casting the return value of an allocator function, which is not advisable. Also, you'd better use sizeof(*myArray) instead of the explicit sizeof(type) construct, because if you later change the type of your array/pointer, and you forget to change the type here also, you'll be facing hard-to-track-down segfault and/or memory leak errors. To sum up:

for(i = 0; i < n; i++){
    int *tmp;
    tmp = realloc(myArray, i*sizeof(*myArray));
    if (tmp == NULL)
    {
        free(myArray);
        /* And handle error */
    }
    myArray = tmp;
}

And oh well, to actually answer your question: you don't need to free().

Upvotes: 6

AnT stands with Russia
AnT stands with Russia

Reputation: 320371

No. Why? The whole point of realloc is that it reallocates the existing memory block, preserving the values already stored in that memory block. The idea is that in some cases it might reuse the existing memory location instead of allocating a completely new memory block and copying the old values there.

If you don't care to preserve the content of the old block, then you might not need realloc at all.

It should also be mentioned that realloc's capabilities also cover malloc's and free's functionality, given the appropriate argument values. What you are doing in the second cycle of your code is essentially using realloc in pure malloc mode.

Upvotes: 2

Related Questions