mirror of
https://git.savannah.gnu.org/git/gnulib.git
synced 2025-08-10 04:43:00 +03:00
* lib/realloc.c (rpl_realloc): Simplify and tune by using HAVE_REALLOC_0_NONNULL and HAVE_MALLOC_PTRDIFF, and by having just one call to realloc instead of two. * lib/reallocarray.c (reallocarray): Simplify and tune by delegating the zero case to the revised realloc. * m4/eealloc.m4 (_AC_FUNC_REALLOC_IF): Since only eealloc uses this macro now, move its definition here ... * m4/realloc.m4: ... from here. (gl_FUNC_REALLOC_0_NONNULL): Also check that realloc (p, 0) returns nonnull. Require gl_FUNC_REALLOC_POSIX. Define HAVE_REALLOC_0_NONNULL. * m4/reallocarray.m4 (gl_FUNC_REALLOCARRAY): Also replace reallocarray if it returns a null pointer for size zero. * modules/eealloc (Files): Remove m4/realloc.m4. * modules/realloc-posix (Depends-on): Add extensions-aix. * modules/reallocarray (Files): Add m4/realloc.m4.
99 lines
3.3 KiB
Plaintext
99 lines
3.3 KiB
Plaintext
@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
|
|
Upon failure, the function does not set @code{errno} to @code{ENOMEM} on
|
|
some platforms:
|
|
mingw, MSVC 14.
|
|
|
|
@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 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. The @code{realloc-posix} module
|
|
implements the latter behavior.
|
|
|
|
Behavior is a real mess for @code{realloc (p, 0)} with non-null @code{p}.
|
|
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 the call
|
|
must set @code{errno} to an implementation-defined value,
|
|
and POSIX.1-2024 extends C17 a bit further by saying that
|
|
the 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, platforms have one of the following behaviors:
|
|
|
|
@enumerate
|
|
@item
|
|
Always free @code{p} without changing @code{errno} and return a null pointer,
|
|
even though this does not conform to POSIX:
|
|
glibc 2.1.1--2.40, most likely glibc 2.41+ at least by default, Android.
|
|
|
|
@item
|
|
Always free @code{p}, possibly set @code{errno}, and return a null pointer:
|
|
mingw, MSVC.
|
|
|
|
@item
|
|
Always free @code{p}, set @code{errno} to @code{EINVAL},
|
|
and return a null pointer:
|
|
AIX 7.3 without @code{_LINUX_SOURCE_COMPAT}.
|
|
|
|
@item
|
|
Always free @code{p} without changing @code{errno}
|
|
and return a pointer to a new region of size zero:
|
|
AIX 7.3 with @code{_LINUX_SOURCE_COMPAT}, glibc 1--2.1,
|
|
perhaps glibc 2.41+ in some configurations.
|
|
|
|
@item
|
|
When successful free @code{p}, possibly set @code{errno},
|
|
and return a pointer to a new region of size zero;
|
|
when unsuccessful do not free @code{p}, set @code{errno},
|
|
and return a null pointer:
|
|
musl libc, macOS, FreeBSD, NetBSD, OpenBSD, Solaris, Cygwin.
|
|
@end enumerate
|
|
|
|
@noindent
|
|
The @code{realloc-posix} module implements behavior (5).
|
|
|
|
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) or (5).
|
|
|
|
@item
|
|
Falsely respond to memory exhaustion (if it wisely checks for
|
|
@code{realloc} failure), or have double-free bugs (if it does not check),
|
|
when it assumes behavior (4) or (5) but the system implements (1), (2) or (3).
|
|
@end itemize
|
|
@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.40 and probably other platforms.
|
|
@end itemize
|