How does realloc handle memory insufficiency?
Asked Answered
T

3

31

If there is not enough memory available at the original location:

  • Does it allocate multiple memory blocks and return a pointer pointing to one of those, with all blocks being internally linked with each other?
  • Does the original region get copied into a new location where enough memory is available?
  • Is a pointer to the new address returned, while the memory at the old location is freed?

Is realloc compiler/OS dependent?

Tennilletennis answered 29/1, 2014 at 16:54 Comment(0)
B
30

realloc attempts to extend your available memory range if sufficient memory is available behind it on the heap. If not then it is equivalent to malloc a block of the new size, memcpy your contents there, free the old block. This is independent of both OS and compiler and depends on the implementation of libc that you link against.

On a similar note: mremap/MREMAP_MAYMOVE (available on modern Linux) will attempt to extend your virtual mapping by the requested size. If that is not possible then it will move your mapping to a new virtual address that has sufficient VM space behind it and then extend your mapping. This is very fast if you are frequently resizing large mappings since no physical copying is done.

Bessette answered 29/1, 2014 at 16:55 Comment(1)
Actually, realloc can also reduce the memory range if the size argument is lower than in the previous call.Ioves
F
20

An implementation of realloc() may look something like the following:

void * realloc(void *ptr, size_t size)
{
    // realloc() on a NULL pointer is the same as malloc().
    if (ptr == NULL)
        return malloc(size);

    size_t oldsize = malloc_getsize(ptr);

    // Are we shrinking an allocation? That's easy.
    if (size < oldsize) {
        malloc_setsize(ptr, size);
        return ptr;
    }

    // Can we grow this allocation in place?
    if (malloc_can_grow(ptr, size)) {
        malloc_setsize(ptr, size);
        return ptr;
    }

    // Create a new allocation, move the data there, and free the old one.
    void *newptr = malloc(size);
    if (newptr == NULL)
        return NULL;
    memcpy(newptr, ptr, oldsize);
    free(ptr);
    return newptr;
}

Note that I'm calling several functions with names starting with malloc_ here. These functions don't actually exist (to the best of my knowledge) in any implementation; they're intended as placeholders for however the allocator actually performs these tasks internally.

Since the implementation of realloc() depends on these internal tools, its implementation is OS-dependent. However, the realloc() interface is universal.

Frisky answered 29/1, 2014 at 18:1 Comment(0)
H
5

If the old pointer can't be resized on place a new one is allocated, the content is copied and the old one is freed.

Hook answered 29/1, 2014 at 16:55 Comment(1)
what do you mean by the old pointer can not be resized on place, can you explain please ?Flavor

© 2022 - 2024 — McMap. All rights reserved.