From man realloc:The realloc() function returns a pointer to the newly allocated memory, which is suitably aligned for any kind of variable and may be different from ptr, or NULL if the request fails.
So in this code snippet:
ptr = (int *) malloc(sizeof(int));
ptr1 = (int *) realloc(ptr, count * sizeof(int));
if(ptr1 == NULL){ //reallocated pointer ptr1
printf("Exiting!!\n");
free(ptr);
exit(0);
}else{
free(ptr); //to deallocate the previous memory block pointed by ptr so as not to leave orphaned blocks of memory when ptr=ptr1 executes and ptr moves on to another block
ptr = ptr1; //deallocation using free has been done assuming that ptr and ptr1 do not point to the same address
}
Is it sufficient to just assume that the reallocated pointer points to a different block of memeory and not to the same block.Because if the assumption becomes false and realloc returns the address of the original memory block pointed to by ptr and then free(ptr) executes(for the reason given in the comments) then the memory block would be erased and the program would go nuts. Should I put in another condition which will compare the equality of ptr and ptr1 and exclude the execution of the free(ptr) statement?
OP: ... may be different from ptr, or NULL if the request fails.
A: Not always.
NULL
may be legitimately returned (not a failure), ifcount
is 0.OP: Is it sufficient to just assume that the reallocated pointer points to a different block of memory and not to the same block.
A: No
OP: Should I put in another condition which will compare the equality of ptr and ptr1 and exclude the execution of the free(ptr) statement?
A: No.
If
realloc()
returnsNULL
(and count is not 0), the value ofptr
is still valid, pointing to the un-resized data.free(ptr)
or not depends on your goals.If
realloc()
returns notNULL
, do notfree(ptr)
, it is all ready freed.Example: https://codereview.stackexchange.com/questions/36662/critique-of-realloc-wrapper
realloc
will return the same address toptr
if it have enough space to extend the actual chunk of memory pointed byptr
. Otherwise, it will move the data to the new chunk and free the old chunk. You can not rely onptr1
being different toptr
. Your program behaves undefined.If
realloc
returns another address, it first deallocates the old one so you don't have to do it yourself.By the way, never cast the return of
malloc/realloc
:). Your code should be like this:You should not
free
your original pointer if therealloc
succeeds. Whether youfree
that pointer if therealloc
fails depends on the needs of your particular application; if you absolutely cannot continue without that additional memory, then this would be a fatal error and you would deallocate any held storage and exit. If, OTOH, you can still continue (perhaps execute a different operation and hope that memory will come available later), the you'd probably want to hold on to that memory and a attempt a anotherrealloc
later.Chapter and verse:
Emphasis added. Note clause 4; the returned pointer may be the same as your original pointer.
If
realloc
moves your data, it will free the old pointer for you behind the scenes. I don't have a copy of the C11 standard, but it is guaranteed in the C99 standard.Just don't call
free()
on your original ptr in the happy path. Essentiallyrealloc()
has done that for you.Applying fixes as edits, based on the good comments below.
Reading this comp.lang.c question, reveals 3 cases:
realloc
cannot find enough space at all, it returns a null pointer, and leaves the previous region allocated."This can be translated directly to code:
So, if you think about it, the code you posted is fine (almost). The above code simplifies to:
Note the extra
else if(ptr != tmp)
, which excludes Case 1, where you wouldn't want to callfree(ptr)
becauseptr
andtmp
refer to the same location. Also, just for safety, I make sure to assignNULL
totmp
to avoid any dangling pointer issues whiletmp
is in scope.