Does it fail when it runs out of free memory similar to malloc
or could there be other reasons?
If realloc() fails, the original block is left untouched; it is not freed or moved. On success, the reallocarray() function returns a pointer to the newly allocated memory. On failure, it returns NULL and the original block of memory is left untouched.
( realloc will always succeed when you request to shrink a block.) If the input pointer is null, then realloc behaves exactly as if you had called malloc(size) , returning a pointer to the newly-allocated block of the requested size, or a null pointer if the request could not be satisfied.
realloc will not fails in shrinking the existing memory, so it will not return NULL .
Return Value If size is 0, the realloc() function returns NULL. If there is not enough storage to expand the block to the given size, the original block is unchanged and the realloc() function returns NULL. The storage to which the return value points is aligned for storage of any type of object.
Any of the allocation functions (malloc
, realloc
, calloc
, and on POSIX, posix_memalign
) could fail for any of the following reasons, and possibly others:
malloc
won't fail in this situation, but instead the OS will later kill one or more programs when it figures out there's not really enough physical memory to go around. But on robust systems (including Linux with overcommit disabled), malloc
will fail if there's no physical memory left.Note that strictly speaking, the allocation functions are allowed to fail at any time for any reason. Minimizing failure is a quality-of-implementation issue. It's also possible that realloc
could fail, even when reducing the size of an object; this could happen on implementations that strictly segregate allocations by size. Of course, in this case you could simply continue to use the old (larger) object.
You should think of realloc
as working this way:
void *realloc(void *oldptr, size_t newsize)
{
size_t oldsize = __extract_size_of_malloc_block(oldptr);
void *newptr = malloc(newsize);
if (!newptr)
return 0;
if (oldsize > newsize)
oldsize = newsize;
memcpy(newptr, oldptr, oldsize);
free(oldptr);
return newptr;
}
An implementation may be able to do specific cases more efficiently than that, but an implementation that works exactly as shown is 100% correct. That means realloc(ptr, newsize)
can fail anytime malloc(newsize)
would have failed; in particular it can fail even if you are shrinking the allocation.
Now, on modern desktop systems there is a strong case for not trying to recover from malloc
failures, but instead wrapping malloc
in a function (usually called xmalloc
) that terminates the program immediately if malloc
fails; naturally the same argument applies to realloc
. The case is:
malloc
to fail, the user will get fed up with their thrashing disk and forcibly terminate your program.malloc
failed (such shims are at best difficult, at worst impossible, to create, depending on the OS) you would have to test order of 2N failure patterns, where N is the number of calls to malloc in your program.Arguments 1 and 2 do not apply to embedded or mobile systems (yet!) but argument 3 is still valid there.
Argument 3 only applies to programs where allocation failures must be checked and propagated at every call site. If you are so lucky as to be using C++ as it is intended to be used (i.e. with exceptions) you can rely on the compiler to create the error recovery paths for you, so the testing burden is much reduced. And in any higher level language worth using nowadays you have both exceptions and a garbage collector, which means you couldn't worry about allocation failures even if you wanted to.
I'd say it mostly implementation specific. Some implementations may be very likely to fail. Some may have other parts of the program fail before realloc will. Always be defensive and check if it does fail.
And remember to free the old pointer that you tried to realloc.
ptr=realloc(ptr,10);
is ALWAYS a possible memory leak.
Always do it rather like this:
void *tmp=ptr;
if(ptr=realloc(ptr,10)==NULL){
free(tmp);
//handle error...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With