[PATCH v2 3/4] Say malloc (0) != NULL is now common; resection

Paul Eggert eggert@cs.ucla.edu
Wed Feb 11 20:17:36 GMT 2026


* manual/memory.texi (Portable Allocation):
New section, split off from Malloc Examples.
Say that almost every system follows glibc's example
in having successful malloc (0) return non-null;
AIX is the only exception nowadays.
Document fundamental alignment portability.
---
 manual/memory.texi | 88 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 68 insertions(+), 20 deletions(-)

diff --git a/manual/memory.texi b/manual/memory.texi
index dab2592ac3..55cb92a0bd 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -318,6 +318,7 @@ any time (or never).
 @menu
 * Basic Allocation::            Simple use of @code{malloc}.
 * Malloc Examples::             Examples of @code{malloc}.  @code{xmalloc}.
+* Portable Allocation::         Portable use of @code{malloc}.
 * Freeing after Malloc::        Use @code{free} to free a block you
 				 got with @code{malloc}.
 * Changing Block Size::         Use @code{realloc} to make a block
@@ -669,19 +670,23 @@ contents of another block.  If you have already allocated a block and
 discover you want it to be bigger, use @code{realloc} (@pxref{Changing
 Block Size}).
 
-@strong{Portability Notes:}
+@node Portable Allocation
+@subsubsection Portable Memory Allocation
+
+More care is needed when allocating memory in
+code intended to run on both GNU and non-GNU systems,
+or when a non-GNU replacement allocator is used (@pxref{Replacing malloc}).
+When storage size is small or outlandishly large,
+or when storage is allocated for a less-common type,
+the POSIX and ISO C standards permit multiple behaviors.
 
 @itemize @bullet
 @item
-In @theglibc{}, a successful @code{malloc (0)}
-returns a non-null pointer to a newly allocated size-zero block;
-other implementations may return @code{NULL} instead.
-POSIX and the ISO C standard allow both behaviors.
-
-@item
-In implementations other than @theglibc{}, a non-null pointer returned
-by @code{malloc (@var{size})} is guaranteed to be aligned only for
-fundamentally-aligned objects of size at most @code{max (@var{size}, 1)}.
+In @theglibc{} and most other systems, a successful @code{malloc (0)}
+returns a non-null pointer to a newly allocated size-zero block.
+However, in IBM AIX a successful @code{malloc (0)} returns a null pointer,
+and this breaks common code such as the implementation of @code{xmalloc}
+given in this manual (@pxref{Malloc Examples}).
 
 @item
 In @theglibc{}, a failed @code{malloc} call sets @code{errno},
@@ -693,6 +698,44 @@ In @theglibc{}, @code{malloc} always fails when @var{size} exceeds
 @code{PTRDIFF_MAX}, to avoid problems with programs that subtract
 pointers or use signed indexes.  Other implementations may succeed in
 this case, leading to undefined behavior later.
+
+@item
+In other implementations, a non-null pointer returned
+by @code{malloc (@var{size})} is guaranteed to be aligned only for
+fundamentally-aligned objects of size at most @code{max (@var{size}, 1)}.
+This may be less than the alignment guaranteed by @theglibc{}.
+
+@item
+Although @theglibc{}'s headers define only types with fundamental alignment,
+the C and POSIX standards require only the following types
+(if available) to have fundamental alignment:
+
+@quotation
+@code{char};
+all integer types (including @code{bool});
+@code{float}, @code{double}, @code{long double};
+@code{_Decimal32}, @code{_Decimal64}, @code{_Decimal128};
+@code{float _Complex}, @code{double _Complex}, @code{long double _Complex};
+all enumerated types;
+all pointer types;
+all array types whose element types have fundamental alignment;
+all struct and union types whose element types all have
+fundamental alignment and that lack stricter alignment specifiers;
+@code{va_list} (in @code{<stdarg.h>});
+@code{fpos_t} (in @code{<stdio.h>});
+@code{cnd_t}, @code{thrd_t}, @code{tss_t}, @code{mtx_t}, @code{once_flag}
+(in @code{<threads.h>});
+@code{mbstate_t} (in @code{<wchar.h>}).
+@end quotation
+
+@noindent
+In theory, portable code should not use @code{malloc} to
+allocate storage containing types not in this list;
+it should instead use functions like @code{aligned_alloc}.
+In practice, though, other implementations generally follow
+@theglibc{}'s lead and define only types with fundamental alignment,
+and it is generally portable to use @code{malloc} to allocate objects
+with types defined by the C library.
 @end itemize
 
 @node Freeing after Malloc
@@ -876,6 +919,8 @@ is left undisturbed.
 Any non-null pointer returned by @code{realloc} satisfies the same
 alignment restrictions as a similar pointer returned by @code{malloc}
 with the same size.
+Any special alignment created by @code{aligned_alloc}
+and similar functions is lost after @code{realloc}.
 @end deftypefun
 
 @deftypefun {void *} reallocarray (void *@var{ptr}, size_t @var{nmemb}, size_t @var{size})
@@ -893,6 +938,13 @@ returning a null pointer, and leaving the original block unchanged.
 @code{reallocarray} should be used instead of @code{realloc} when the new size
 of the allocated block is the result of a multiplication that might overflow.
 
+In @theglibc{}, the vector is aligned the same way that @code{malloc}
+aligns its returned values.  In other implementations, it is merely
+aligned suitably for any array of fundamentally-aligned elements each
+with size at most @code{max (@var{size}, 1)}.
+Any special alignment created by @code{aligned_alloc}
+and similar functions is lost after @code{reallocarray}.
+
 This function was originally derived from OpenBSD 5.6, but was added in
 POSIX.1-2024.
 @end deftypefun
@@ -987,15 +1039,9 @@ is declared in @file{stdlib.h}.
 @c  chunk_is_mmapped dup ok
 @c  MALLOC_ZERO ok
 @c   memset dup ok
-This function allocates a block long enough to contain a vector of
-@var{count} elements, each of size @var{eltsize}.  Its contents are
-cleared to zero before @code{calloc} returns.
-
-In @theglibc{}, the vector is aligned the same way that @code{malloc}
-aligns its returned values.  In other implementations, it is merely
-aligned suitably for any array of fundamentally-aligned elements each
-with size at most @code{max (@var{size}, 1)}.
-
+This function allocates a zeroed vector.  It acts like
+@code{reallocarray (NULL, @var{count}, @var{eltsize})} except that the
+vector's contents are cleared to zero before @code{calloc} returns.
 @end deftypefun
 
 You could define @code{calloc} as follows:
@@ -1927,7 +1973,9 @@ functions (that is, all the functions used by the application,
 failures, and, at run time, to heap corruption and application crashes.
 Replacement functions should implement the behavior documented for
 their counterparts in @theglibc{}; for example, the replacement
-@code{free} should also preserve @code{errno}.
+@code{malloc} should return a null pointer only when failing
+and should return pointers aligned to @code{alignof (max_align_t)},
+and the replacement @code{free} should preserve @code{errno}.
 
 The minimum set of functions which has to be provided by a custom
 @code{malloc} is given in the table below.
-- 
2.51.0



More information about the Libc-alpha mailing list