mirror of
git://sourceware.org/git/glibc.git
synced 2026-11-14 07:12:13 +08:00
Say malloc (0) != NULL is now common; resection
* 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. Have examples match the new text, and use NULL rather than 0. Reviewed-by: Florian Weimer <fweimer@redhat.com>
This commit is contained in:
+92
-40
@@ -318,6 +318,7 @@ any time (or never).
|
|||||||
@menu
|
@menu
|
||||||
* Basic Allocation:: Simple use of @code{malloc}.
|
* Basic Allocation:: Simple use of @code{malloc}.
|
||||||
* Malloc Examples:: Examples of @code{malloc}. @code{xmalloc}.
|
* 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
|
* Freeing after Malloc:: Use @code{free} to free a block you
|
||||||
got with @code{malloc}.
|
got with @code{malloc}.
|
||||||
* Changing Block Size:: Use @code{realloc} to make a block
|
* Changing Block Size:: Use @code{realloc} to make a block
|
||||||
@@ -621,7 +622,7 @@ If no more space is available, @code{malloc} returns a null pointer.
|
|||||||
You should check the value of @emph{every} call to @code{malloc}. It is
|
You should check the value of @emph{every} call to @code{malloc}. It is
|
||||||
useful to write a subroutine that calls @code{malloc} and reports an
|
useful to write a subroutine that calls @code{malloc} and reports an
|
||||||
error if the value is a null pointer, returning only if the value is
|
error if the value is a null pointer, returning only if the value is
|
||||||
nonzero. This function is conventionally called @code{xmalloc}. Here
|
non-null. This function is conventionally called @code{xmalloc}. Here
|
||||||
it is:
|
it is:
|
||||||
@cindex @code{xmalloc} function
|
@cindex @code{xmalloc} function
|
||||||
|
|
||||||
@@ -629,10 +630,10 @@ it is:
|
|||||||
void *
|
void *
|
||||||
xmalloc (size_t size)
|
xmalloc (size_t size)
|
||||||
@{
|
@{
|
||||||
void *value = malloc (size);
|
void *p = malloc (size);
|
||||||
if (value == 0)
|
if (p == NULL)
|
||||||
fatal ("virtual memory exhausted");
|
fatal ("virtual memory exhausted");
|
||||||
return value;
|
return p;
|
||||||
@}
|
@}
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
@@ -645,9 +646,9 @@ a newly allocated null-terminated string:
|
|||||||
char *
|
char *
|
||||||
savestring (const char *ptr, size_t len)
|
savestring (const char *ptr, size_t len)
|
||||||
@{
|
@{
|
||||||
char *value = xmalloc (len + 1);
|
char *p = xmalloc (len + 1);
|
||||||
value[len] = '\0';
|
p[len] = '\0';
|
||||||
return memcpy (value, ptr, len);
|
return memcpy (p, ptr, len);
|
||||||
@}
|
@}
|
||||||
@end group
|
@end group
|
||||||
@end smallexample
|
@end smallexample
|
||||||
@@ -669,26 +670,28 @@ contents of another block. If you have already allocated a block and
|
|||||||
discover you want it to be bigger, use @code{realloc} (@pxref{Changing
|
discover you want it to be bigger, use @code{realloc} (@pxref{Changing
|
||||||
Block Size}).
|
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
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
In @theglibc{}, a successful @code{malloc (0)}
|
In most systems, a successful @code{malloc (0)}
|
||||||
returns a non-null pointer to a newly allocated size-zero block;
|
returns a non-null pointer to a newly allocated size-zero block.
|
||||||
other implementations may return @code{NULL} instead.
|
However, IBM AIX is unusual in that a successful @code{malloc (0)}
|
||||||
POSIX and the ISO C standard allow both behaviors.
|
returns a null pointer, and this breaks common code such as the
|
||||||
|
implementation of @code{xmalloc} given in this manual. @xref{Malloc Examples}.
|
||||||
@item
|
Code intended to be portable to IBM AIX can use
|
||||||
In @theglibc{}, a non-null pointer returned by @code{malloc (@var{size})}
|
@code{p = malloc (size | (size == 0))} instead of @code{p = malloc (size)},
|
||||||
is a multiple of @code{alignof (max_align_t)} when converted to an integer.
|
or if it does not mind a null pointer on success it can replace the following
|
||||||
Other implementations may align the result only to what is needed for
|
@code{if (p == NULL) fatal (...);} with
|
||||||
fundamentally-aligned objects of size at most @code{max (@var{size}, 1)}.
|
@code{if (p == NULL && size != 0) fatal (...);}.
|
||||||
For example, if @code{alignof (max_align_t)} is 16 but smaller
|
|
||||||
fundamentally-aligned objects all have alignment of at most 4,
|
|
||||||
other implementations of @code{malloc (15)} might return
|
|
||||||
a pointer that is a multiple of 4 but not of 16 or even of 8.
|
|
||||||
Portable code should therefore use a function like @code{aligned_alloc}
|
|
||||||
if it needs @code{alignof (max_align_t)} alignment even for small allocations.
|
|
||||||
|
|
||||||
@item
|
@item
|
||||||
In @theglibc{}, a failed @code{malloc} call sets @code{errno},
|
In @theglibc{}, a failed @code{malloc} call sets @code{errno},
|
||||||
@@ -700,6 +703,50 @@ In @theglibc{}, @code{malloc} always fails when @var{size} exceeds
|
|||||||
@code{PTRDIFF_MAX}, to avoid problems with programs that subtract
|
@code{PTRDIFF_MAX}, to avoid problems with programs that subtract
|
||||||
pointers or use signed indexes. Other implementations may succeed in
|
pointers or use signed indexes. Other implementations may succeed in
|
||||||
this case, leading to undefined behavior later.
|
this case, leading to undefined behavior later.
|
||||||
|
|
||||||
|
@item
|
||||||
|
In @theglibc{}, @code{malloc (@var{size})} returns a pointer that when
|
||||||
|
converted to an integer is a multiple of @code{alignof (max_align_t)}.
|
||||||
|
Some other implementations may align the result only to what is needed for
|
||||||
|
fundamentally-aligned objects of size at most @code{max (@var{size}, 1)}.
|
||||||
|
For example, if @code{alignof (max_align_t)} is 16 but smaller
|
||||||
|
fundamentally-aligned objects all have alignment of at most 4,
|
||||||
|
other implementations of @code{malloc (15)} might return
|
||||||
|
a pointer that is a multiple of 4 but not of 16 or even of 8.
|
||||||
|
Portable code should therefore use a function like @code{aligned_alloc}
|
||||||
|
if it needs @code{alignof (max_align_t)} alignment even for small allocations.
|
||||||
|
|
||||||
|
@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
|
@end itemize
|
||||||
|
|
||||||
@node Freeing after Malloc
|
@node Freeing after Malloc
|
||||||
@@ -883,6 +930,8 @@ is left undisturbed.
|
|||||||
Any non-null pointer returned by @code{realloc} satisfies the same
|
Any non-null pointer returned by @code{realloc} satisfies the same
|
||||||
alignment restrictions as a similar pointer returned by @code{malloc}
|
alignment restrictions as a similar pointer returned by @code{malloc}
|
||||||
with the same size.
|
with the same size.
|
||||||
|
Any special alignment created by @code{aligned_alloc}
|
||||||
|
and similar functions is lost after @code{realloc}.
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
@deftypefun {void *} reallocarray (void *@var{ptr}, size_t @var{nmemb}, size_t @var{size})
|
@deftypefun {void *} reallocarray (void *@var{ptr}, size_t @var{nmemb}, size_t @var{size})
|
||||||
@@ -900,6 +949,13 @@ returning a null pointer, and leaving the original block unchanged.
|
|||||||
@code{reallocarray} should be used instead of @code{realloc} when the new size
|
@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.
|
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 may be 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
|
This function was originally derived from OpenBSD 5.6, but was added in
|
||||||
POSIX.1-2024.
|
POSIX.1-2024.
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
@@ -922,8 +978,8 @@ as @code{xmalloc} does for @code{malloc}:
|
|||||||
void *
|
void *
|
||||||
xreallocarray (void *ptr, size_t nmemb, size_t size)
|
xreallocarray (void *ptr, size_t nmemb, size_t size)
|
||||||
@{
|
@{
|
||||||
void *value = reallocarray (ptr, nmemb, size);
|
void *p = reallocarray (ptr, nmemb, size);
|
||||||
if (value == 0)
|
if (p == NULL)
|
||||||
fatal ("Virtual memory exhausted");
|
fatal ("Virtual memory exhausted");
|
||||||
return value;
|
return value;
|
||||||
@}
|
@}
|
||||||
@@ -994,15 +1050,9 @@ is declared in @file{stdlib.h}.
|
|||||||
@c chunk_is_mmapped dup ok
|
@c chunk_is_mmapped dup ok
|
||||||
@c MALLOC_ZERO ok
|
@c MALLOC_ZERO ok
|
||||||
@c memset dup ok
|
@c memset dup ok
|
||||||
This function allocates a block long enough to contain a vector of
|
This function allocates a zeroed vector. It acts like
|
||||||
@var{count} elements, each of size @var{eltsize}. Its contents are
|
@code{reallocarray (NULL, @var{count}, @var{eltsize})} except that the
|
||||||
cleared to zero before @code{calloc} returns.
|
vector's 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)}.
|
|
||||||
|
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
You could define @code{calloc} as follows:
|
You could define @code{calloc} as follows:
|
||||||
@@ -1011,10 +1061,10 @@ You could define @code{calloc} as follows:
|
|||||||
void *
|
void *
|
||||||
calloc (size_t count, size_t eltsize)
|
calloc (size_t count, size_t eltsize)
|
||||||
@{
|
@{
|
||||||
void *value = reallocarray (0, count, eltsize);
|
void *p = reallocarray (0, count, eltsize);
|
||||||
if (value != 0)
|
if (p != NULL)
|
||||||
memset (value, 0, count * eltsize);
|
memset (p, 0, count * eltsize);
|
||||||
return value;
|
return p;
|
||||||
@}
|
@}
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
@@ -1934,7 +1984,9 @@ functions (that is, all the functions used by the application,
|
|||||||
failures, and, at run time, to heap corruption and application crashes.
|
failures, and, at run time, to heap corruption and application crashes.
|
||||||
Replacement functions should implement the behavior documented for
|
Replacement functions should implement the behavior documented for
|
||||||
their counterparts in @theglibc{}; for example, the replacement
|
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,
|
||||||
|
it 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
|
The minimum set of functions which has to be provided by a custom
|
||||||
@code{malloc} is given in the table below.
|
@code{malloc} is given in the table below.
|
||||||
|
|||||||
Reference in New Issue
Block a user