Changing Block Size (The GNU C Library)

#### 3.2.3.5 Changing the Size of a Block ¶

Often you do not know for certain how big a block you will ultimately need at the time you must begin to use the block. For example, the block might be a buffer that you use to hold a line being read from a file; no matter how long you make the buffer initially, you may encounter a line that is longer.

You can make the block longer by calling `realloc` or `reallocarray`. These functions are declared in `stdlib.h`.

Function: `void *` realloc `(void *ptr, size_t newsize)` ¶

  Preliminary: | MT-Safe | AS-Unsafe lock | AC-Unsafe lock fd mem | See POSIX Safety Concepts.

  The `realloc` function changes the size of the block whose address is ptr to be newsize.

  Since the space after the end of the block may be in use, `realloc` may find it necessary to copy the block to a new address where more free space is available. The value of `realloc` is the new address of the block. If the block needs to be moved, `realloc` copies the old contents.

  If you pass a null pointer for ptr, `realloc` behaves just like ‘`malloc (newsize)`’. Otherwise, if newsize is zero `realloc` frees the block and returns `NULL`. Otherwise, if `realloc` cannot reallocate the requested size it returns `NULL` and sets `errno`; the original block is left undisturbed.

  Any non-null pointer returned by `realloc` satisfies the same alignment restrictions as a similar pointer returned by `malloc` with the same size. Any special alignment created by `aligned_alloc` and similar functions is lost after `realloc`.

Function: `void *` reallocarray `(void *ptr, size_t nmemb, size_t size)` ¶

  Preliminary: | MT-Safe | AS-Unsafe lock | AC-Unsafe lock fd mem | See POSIX Safety Concepts.

  The `reallocarray` function changes the size of the block whose address is ptr to be long enough to contain a vector of nmemb elements, each of size size. It is equivalent to ‘`realloc (ptr, nmemb * size)`’, except that `reallocarray` fails safely if the multiplication overflows, by setting `errno` to `ENOMEM`, returning a null pointer, and leaving the original block unchanged.

  `reallocarray` should be used instead of `realloc` when the new size of the allocated block is the result of a multiplication that might overflow.

  In the GNU C Library, the vector is aligned the same way that `malloc` aligns its returned values. In other implementations, it may be merely aligned suitably for any array of fundamentally-aligned elements each with size at most `max (size, 1)`. Any special alignment created by `aligned_alloc` and similar functions is lost after `reallocarray`.

  This function was originally derived from OpenBSD 5.6, but was added in POSIX.1-2024.

Like `malloc`, `realloc` and `reallocarray` may return a null pointer if no memory space is available to make the block bigger. When this happens, the original block is untouched; it has not been modified or relocated.

In most cases it makes no difference what happens to the original block when `realloc` fails, because the application program cannot continue when it is out of memory, and the only thing to do is to give a fatal error message. Often it is convenient to write and use subroutines, conventionally called `xrealloc` and `xreallocarray`, that take care of the error message as `xmalloc` does for `malloc`:

    void *
    xreallocarray (void *ptr, size_t nmemb, size_t size)
    {
      void *p = reallocarray (ptr, nmemb, size);
      if (p == NULL)
        fatal ("Virtual memory exhausted");
      return value;
    }

    void *
    xrealloc (void *ptr, size_t size)
    {
      return xreallocarray (ptr, 1, size);
    }

You can also use `realloc` or `reallocarray` to make a block smaller. The reason you would do this is to avoid tying up a lot of memory space when only a little is needed. In several allocation implementations, making a block smaller sometimes necessitates copying it, so it can fail if no other space is available.

Portability Notes:

- Portable programs should not attempt to reallocate blocks to be size zero. On other implementations if ptr is non-null, `realloc (ptr, 0)` might free the block and return a non-null pointer to a size-zero object, or it might fail and return `NULL` without freeing the block. The ISO C17 standard allows these variations.
- In the GNU C Library, reallocation fails if the resulting block would exceed `PTRDIFF_MAX` in size, to avoid problems with programs that subtract pointers or use signed indexes. Other implementations may succeed, leading to undefined behavior later.
- In the GNU C Library, if the new size is the same as the old, `realloc` and `reallocarray` are guaranteed to change nothing and return the same address that you gave. However, POSIX and ISO C allow the functions to relocate the object or fail in this situation.