Hash :
fbaddca3
Author :
Date :
2025-02-08T14:31:04
doc: some updates for glibc 2.41
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
@node realloc
@subsection @code{realloc}
@findex realloc
POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9799919799/functions/realloc.html}
Gnulib module: realloc-posix
@mindex realloc-posix
Portability problems fixed by Gnulib:
@itemize
@item
On some platforms, when the function fails it does not set @code{errno}:
mingw, MSVC 14.
@item
On some platforms, when the function fails it might set @code{errno}
to @code{EAGAIN} instead of to @code{ENOMEM}. Although POSIX allows
@code{EAGAIN}, the @code{realloc-posix} module insists on @code{ENOMEM}
which also conforms to POSIX and is GNU-compatible:
Solaris 11.4.
@item
On some platforms, @code{realloc (p, n)} can succeed even if @code{n}
exceeds @code{PTRDIFF_MAX}. Although this behavior is arguably
allowed by POSIX it is not compatible with GNU and
can lead to behavior not defined by POSIX later,
so @code{realloc-posix} does not allow going over the limit.
@item
It is not portable to call @code{realloc} with a size of 0.
With a null pointer argument, this is the same ambiguity as @code{malloc (0)}
as to whether a successful call returns a null pointer or a pointer to a
new zero-sized memory region. Although both behaviors conform to POSIX,
@code{realloc-posix} insists on the latter behavior, which is
compatible with GNU.
With non-null @code{p}, behavior is a real mess for @code{realloc (p, 0)}.
C23 says behavior is undefined.
C89 through C17 say a successful call returns either a null pointer
or a pointer to a new zero-sized memory region.
POSIX.1-2017 extends C99 by saying that if a successful call
returns a null pointer it
must also set @code{errno} to an implementation-defined value,
and POSIX.1-2024 extends C17 a bit further by saying that
such a call must set @code{errno} to @code{EINVAL}.
It is not known what POSIX.1-2024's successor will say,
though presumably it will extend C23.
In practice, successful @code{realloc (p, 0)} calls
have one of the following behaviors:
@enumerate
@item
Free @code{p}, do not change @code{errno}, and return a null pointer:
glibc 2.33--2.41 by default, Android.
@item
Free @code{p}, possibly set @code{errno}, and return a null pointer:
glibc 1--2.1 if specially built with @code{REALLOC_ZERO_BYTES_FREES=1},
glibc 2.1.1--2.32 by default,
mingw, MSVC 14.
@item
Free @code{p}, set @code{errno} to @code{EINVAL}, and return a null pointer:
AIX 7.3 without @code{_LINUX_SOURCE_COMPAT}.
@item
Free @code{p} and return a pointer to a new region of size zero:
AIX 7.3 with @code{_LINUX_SOURCE_COMPAT}, glibc 1--2.1 by default,
glibc 2.1.1--2.41 if specially built with @code{REALLOC_ZERO_BYTES_FREES=0},
musl libc, macOS, FreeBSD, NetBSD, OpenBSD, Solaris, Cygwin.
@end enumerate
@noindent
Behaviors (3) and (4) conform to POSIX; behaviors (1) and (2) do not.
The @code{realloc-posix} module insists on behavior (4) as it is more
popular than (3) and is more useful in practice. Behavior (4) is the
only one of the four in which returning a null pointer means failure,
which is what non-expert programmers typically expect.
A program not suspecting these variations in semantics will either:
@itemize
@item
Leak memory (the still-valid @code{p}) if it unwisely does not check
for @code{realloc} failure, when it assumes behavior (1), (2) or (3) but the
system implements behavior (4).
@item
Falsely respond to memory exhaustion (if it wisely checks for @code{realloc}
failure), or have double-free bugs (if it unwisely does not check),
when it assumes behavior (4) but the system implements (1), (2) or (3).
@end itemize
@item
When @code{realloc (p, 0)} sets errno to @code{EINVAL} and returns null,
a POSIX.1-2024 application cannot tell whether the call has succeeded
and freed @code{p}, or has failed without freeing @code{p}.
This is only a theoretical problem, though, as the only practical
implementation with this behavior is AIX without @code{_LINUX_SOURCE_COMPAT},
which behaves this way only when the call succeeds.
@end itemize
Portability problems not fixed by Gnulib:
@itemize
@item
When not growing an already-allocated region, i.e.,
when @code{p} points to a region of size @code{psize} and @code{n <= psize},
@code{realloc (p, n)} can fail and return a null pointer:
glibc 2.41 and probably other platforms.
@end itemize