Reputation: 2176
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
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
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
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
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