reallocarray(3bsd) | 3bsd | reallocarray(3bsd) |
reallocarray
,
recallocarray
, freezero
— memory allocation and deallocation
library “libbsd”
#include
<stdlib.h>
(See
libbsd(7) for include usage.)
void *
reallocarray
(void
*ptr, size_t nmemb,
size_t size);
void *
recallocarray
(void
*ptr, size_t
oldnmemb, size_t
nmemb, size_t
size);
void
freezero
(void
*ptr, size_t
size);
Designed for safe allocation of arrays, the
reallocarray
()
function is similar to realloc
() except it operates
on nmemb members of size size
and checks for integer overflow in the calculation
nmemb * size.
Used for the allocation of memory holding
sensitive data, the
recallocarray
()
function guarantees that memory becoming unallocated is explicitly
discarded,
meaning cached free objects are cleared with
explicit_bzero(3).
The
recallocarray
()
function is similar to reallocarray
() except it
ensures newly allocated memory is cleared similar to
calloc
(). If ptr is
NULL
, oldnmemb is ignored and
the call is equivalent to calloc
(). If
ptr is not NULL
,
oldnmemb must be a value such that
oldnmemb * size is the size of
the earlier allocation that returned ptr, otherwise
the behavior is undefined. The freezero
() function
is similar to the
free
()
function except it ensures memory is explicitly discarded. If
ptr is NULL
, no action occurs.
If ptr is not NULL
, the
size argument must be equal to or smaller than the
size of the earlier allocation that returned ptr.
freezero
() guarantees the memory range starting at
ptr with length size is
discarded while deallocating the whole object originally allocated.
The reallocarray
() and
recallocarray
() functions return a pointer to the
allocated space if successful; otherwise, a null pointer is returned and
errno is set to ENOMEM
.
If multiplying nmemb and
size results in integer overflow,
reallocarray
() and
recallocarray
() return NULL
and set errno to ENOMEM
.
If ptr is not NULL
and multiplying oldnmemb and
size results in integer overflow
recallocarray
() returns NULL
and sets errno to EINVAL
.
Consider
calloc
()
or the extensions reallocarray
() and
recallocarray
() when there is multiplication in the
size argument of malloc
() or
realloc
(). For example, avoid this common idiom as
it may lead to integer overflow:
if ((p = malloc(num * size)) == NULL) err(1, NULL);
A drop-in replacement is
reallocarray
():
if ((p = reallocarray(NULL, num, size)) == NULL) err(1, NULL);
Alternatively,
calloc
()
may be used at the cost of initialization overhead.
When using
realloc
(),
be careful to avoid the following idiom:
size += 50; if ((p = realloc(p, size)) == NULL) return (NULL);
Do not adjust the variable describing how much memory has been
allocated until the allocation has been successful. This can cause aberrant
program behavior if the incorrect size value is used. In most cases, the
above sample will also result in a leak of memory. As stated earlier, a
return value of NULL
indicates that the old object
still remains allocated. Better code looks like this:
newsize = size + 50; if ((newp = realloc(p, newsize)) == NULL) { free(p); p = NULL; size = 0; return (NULL); } p = newp; size = newsize;
As with
malloc
(), it
is important to ensure the new size value will not overflow; i.e. avoid
allocations like the following:
if ((newp = realloc(p, num * size)) == NULL) { ...
Instead, use
reallocarray
():
if ((newp = reallocarray(p, num, size)) == NULL) { ...
Calling
realloc
()
with a NULL
ptr is equivalent
to calling malloc
(). Instead of this idiom:
if (p == NULL) newp = malloc(newsize); else newp = realloc(p, newsize);
Use the following:
newp = realloc(p, newsize);
The
recallocarray
()
function should be used for resizing objects containing sensitive data like
keys. To avoid leaking information, it guarantees memory is cleared before
placing it on the internal free list. Deallocation of such an object should
be done by calling
freezero
().
The reallocarray
() function appeared in
OpenBSD 5.6, DragonFly 5.5
and glibc 2.26.
The recallocarray
() function appeared in
OpenBSD 6.1 and DragonFly
5.5. The freezero
() function appeared in
OpenBSD 6.2 and DragonFly
5.5.
September 14, 2019 | x86_64 |