Import reallocarray(3) from OpenBSD
Add a manpage for it, assign the copyright to the OpenBSD project on it since it is mostly copy/paste from OpenBSD manpage. style(9) fixes Differential Revision: https://reviews.freebsd.org/D2420 Reviewed by: kib
This commit is contained in:
parent
24f93ee714
commit
450dfafb15
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=282314
@ -111,6 +111,9 @@ long double
|
|||||||
strtold(const char * __restrict, char ** __restrict);
|
strtold(const char * __restrict, char ** __restrict);
|
||||||
unsigned long
|
unsigned long
|
||||||
strtoul(const char * __restrict, char ** __restrict, int);
|
strtoul(const char * __restrict, char ** __restrict, int);
|
||||||
|
#ifdef __BSD_VISIBLE
|
||||||
|
void *reallocarray(void *, size_t, size_t);
|
||||||
|
#endif
|
||||||
int system(const char *);
|
int system(const char *);
|
||||||
int wctomb(char *, wchar_t);
|
int wctomb(char *, wchar_t);
|
||||||
size_t wcstombs(char * __restrict, const wchar_t * __restrict, size_t);
|
size_t wcstombs(char * __restrict, const wchar_t * __restrict, size_t);
|
||||||
|
@ -10,7 +10,8 @@ MISRCS+=_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \
|
|||||||
insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \
|
insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \
|
||||||
merge.c mergesort_b.c ptsname.c qsort.c qsort_r.c quick_exit.c \
|
merge.c mergesort_b.c ptsname.c qsort.c qsort_r.c quick_exit.c \
|
||||||
radixsort.c rand.c \
|
radixsort.c rand.c \
|
||||||
random.c reallocf.c realpath.c remque.c strfmon.c strtoimax.c \
|
random.c reallocarray.c reallocf.c realpath.c remque.c strfmon.c \
|
||||||
|
strtoimax.c \
|
||||||
strtol.c strtoll.c strtoq.c strtoul.c strtonum.c strtoull.c \
|
strtol.c strtoll.c strtoq.c strtoul.c strtonum.c strtoull.c \
|
||||||
strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c
|
strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 \
|
|||||||
hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \
|
hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \
|
||||||
lsearch.3 memory.3 ptsname.3 qsort.3 \
|
lsearch.3 memory.3 ptsname.3 qsort.3 \
|
||||||
quick_exit.3 \
|
quick_exit.3 \
|
||||||
radixsort.3 rand.3 random.3 reallocf.3 \
|
radixsort.3 rand.3 random.3 reallocarray.3 reallocf.3 \
|
||||||
realpath.3 strfmon.3 strtod.3 strtol.3 strtonum.3 strtoul.3 system.3 \
|
realpath.3 strfmon.3 strtod.3 strtol.3 strtonum.3 strtoul.3 system.3 \
|
||||||
tsearch.3
|
tsearch.3
|
||||||
|
|
||||||
|
@ -113,6 +113,7 @@ FBSD_1.4 {
|
|||||||
hcreate_r;
|
hcreate_r;
|
||||||
hdestroy_r;
|
hdestroy_r;
|
||||||
hsearch_r;
|
hsearch_r;
|
||||||
|
reallocarray;
|
||||||
};
|
};
|
||||||
|
|
||||||
FBSDprivate_1.0 {
|
FBSDprivate_1.0 {
|
||||||
|
136
lib/libc/stdlib/reallocarray.3
Normal file
136
lib/libc/stdlib/reallocarray.3
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
.\" Copyright (c) 2015 OpenBSD
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" This code is derived from software contributed to Berkeley by
|
||||||
|
.\" the American National Standards Committee X3, on Information
|
||||||
|
.\" Processing Systems.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.\"
|
||||||
|
.Dd May 1, 2015
|
||||||
|
.Dt REALLOCARRAY 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm reallocarray
|
||||||
|
.Nd memory reallocation function
|
||||||
|
.Sh LIBRARY
|
||||||
|
.Lb libc
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In stdlib.h
|
||||||
|
.Ft void *
|
||||||
|
.Fn reallocarray "void *ptr" "size_t nmemb" "size_t size"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Fn reallocarray
|
||||||
|
except it operates on
|
||||||
|
.Fa nmemb
|
||||||
|
members of size
|
||||||
|
.Fa size
|
||||||
|
and checks for integer overflow in the calculation
|
||||||
|
.Fa nmemb
|
||||||
|
*
|
||||||
|
.Fa size .
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
.Fn reallocarray
|
||||||
|
return a pointer to the allocated space; otherwise, a
|
||||||
|
.Dv NULL
|
||||||
|
pointer is returned and
|
||||||
|
.Va errno
|
||||||
|
is set to
|
||||||
|
.Er ENOMEM .
|
||||||
|
.Sh EXAMPLES
|
||||||
|
Consider
|
||||||
|
.Fn reallocarray
|
||||||
|
when there is multiplication in the
|
||||||
|
.Fa size
|
||||||
|
argument of
|
||||||
|
.Fn malloc
|
||||||
|
or
|
||||||
|
.Fn realloc .
|
||||||
|
For example, avoid this common idiom as it may lead to integer overflow:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
if ((p = malloc(num * size)) == NULL)
|
||||||
|
err(1, "malloc");
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
A drop-in replacement is the
|
||||||
|
.Ox
|
||||||
|
extension
|
||||||
|
.Fn reallocarray :
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
if ((p = reallocarray(NULL, num, size)) == NULL)
|
||||||
|
err(1, "reallocarray");
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
When using
|
||||||
|
.Fn realloc ,
|
||||||
|
be careful to avoid the following idiom:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
size += 50;
|
||||||
|
if ((p = realloc(p, size)) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
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
|
||||||
|
.Dv NULL
|
||||||
|
indicates that the old object still remains allocated.
|
||||||
|
Better code looks like this:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
newsize = size + 50;
|
||||||
|
if ((newp = realloc(p, newsize)) == NULL) {
|
||||||
|
free(p);
|
||||||
|
p = NULL;
|
||||||
|
size = 0;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
p = newp;
|
||||||
|
size = newsize;
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
As with
|
||||||
|
.Fn malloc ,
|
||||||
|
it is important to ensure the new size value will not overflow;
|
||||||
|
i.e. avoid allocations like the following:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
if ((newp = realloc(p, num * size)) == NULL) {
|
||||||
|
...
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
Instead, use
|
||||||
|
.Fn reallocarray :
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
if ((newp = reallocarray(p, num, size)) == NULL) {
|
||||||
|
...
|
||||||
|
.Ed
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr realloc 3
|
||||||
|
.Sh HISTORY
|
||||||
|
The
|
||||||
|
.Fn reallocf
|
||||||
|
function first appeared in
|
||||||
|
.Ox 5.6 .
|
42
lib/libc/stdlib/reallocarray.c
Normal file
42
lib/libc/stdlib/reallocarray.c
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
|
||||||
|
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
|
||||||
|
*/
|
||||||
|
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
|
||||||
|
|
||||||
|
void *
|
||||||
|
reallocarray(void *optr, size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
|
||||||
|
nmemb > 0 && SIZE_MAX / nmemb < size) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
return (realloc(optr, size * nmemb));
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user