mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-01 01:41:01 -08:00
Split 'xpalloc' into two functions
The new function 'xpalloc_nbytes' calculates the new size without performing the actual allocation. * src/alloc.c (xpalloc_nbytes): New function. (xpalloc): Use it.
This commit is contained in:
parent
90bcde0139
commit
eae38efc43
2 changed files with 48 additions and 20 deletions
67
src/alloc.c
67
src/alloc.c
|
|
@ -801,32 +801,25 @@ xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size)
|
|||
}
|
||||
|
||||
|
||||
/* Grow PA, which points to an array of *NITEMS items, and return the
|
||||
location of the reallocated array, updating *NITEMS to reflect its
|
||||
new size. The new array will contain at least NITEMS_INCR_MIN more
|
||||
items, but will not contain more than NITEMS_MAX items total.
|
||||
ITEM_SIZE is the size of each item, in bytes.
|
||||
/* Calculate the new allocation size for xpalloc, for growing PA, which
|
||||
points to an array of *NITEMS items, and return the size of the new
|
||||
allocation, updating *NITEMS to reflect this new size. This new array
|
||||
would contain at least NITEMS_INCR_MIN more items, but will not
|
||||
contain more than NITEMS_MAX items total. ITEM_SIZE is the size of
|
||||
each item, in bytes.
|
||||
|
||||
ITEM_SIZE and NITEMS_INCR_MIN must be positive. *NITEMS must be
|
||||
nonnegative. If NITEMS_MAX is -1, it is treated as if it were
|
||||
infinity.
|
||||
|
||||
If PA is null, then allocate a new array instead of reallocating
|
||||
the old one.
|
||||
If PA is null, then calculate the size of a new array.
|
||||
|
||||
Block interrupt input as needed. If memory exhaustion occurs, set
|
||||
*NITEMS to zero if PA is null, and signal an error (i.e., do not
|
||||
return).
|
||||
If memory exhaustion is certain to occur, set *NITEMS to zero if PA
|
||||
is null, and signal an error (i.e., do not return). */
|
||||
|
||||
Thus, to grow an array A without saving its old contents, do
|
||||
{ xfree (A); A = NULL; A = xpalloc (NULL, &AITEMS, ...); }.
|
||||
The A = NULL avoids a dangling pointer if xpalloc exhausts memory
|
||||
and signals an error, and later this code is reexecuted and
|
||||
attempts to free A. */
|
||||
|
||||
void *
|
||||
xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min,
|
||||
ptrdiff_t nitems_max, ptrdiff_t item_size)
|
||||
ptrdiff_t
|
||||
xpalloc_nbytes (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min,
|
||||
ptrdiff_t nitems_max, ptrdiff_t item_size)
|
||||
{
|
||||
ptrdiff_t n0 = *nitems;
|
||||
eassume (0 < item_size && 0 < nitems_incr_min && 0 <= n0 && -1 <= nitems_max);
|
||||
|
|
@ -864,8 +857,42 @@ xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min,
|
|||
|| (0 <= nitems_max && nitems_max < n)
|
||||
|| ckd_mul (&nbytes, n, item_size)))
|
||||
memory_full (SIZE_MAX);
|
||||
pa = xrealloc (pa, nbytes);
|
||||
*nitems = n;
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
/* Grow PA, which points to an array of *NITEMS items, and return the
|
||||
location of the reallocated array, updating *NITEMS to reflect its
|
||||
new size. The new array will contain at least NITEMS_INCR_MIN more
|
||||
items, but will not contain more than NITEMS_MAX items total.
|
||||
ITEM_SIZE is the size of each item, in bytes.
|
||||
|
||||
ITEM_SIZE and NITEMS_INCR_MIN must be positive. *NITEMS must be
|
||||
nonnegative. If NITEMS_MAX is -1, it is treated as if it were
|
||||
infinity.
|
||||
|
||||
If PA is null, then allocate a new array instead of reallocating
|
||||
the old one.
|
||||
|
||||
Block interrupt input as needed. If memory exhaustion occurs, set
|
||||
*NITEMS to zero if PA is null, and signal an error (i.e., do not
|
||||
return).
|
||||
|
||||
Thus, to grow an array A without saving its old contents, do
|
||||
{ xfree (A); A = NULL; A = xpalloc (NULL, &AITEMS, ...); }.
|
||||
The A = NULL avoids a dangling pointer if xpalloc exhausts memory
|
||||
and signals an error, and later this code is reexecuted and
|
||||
attempts to free A. */
|
||||
|
||||
void *
|
||||
xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min,
|
||||
ptrdiff_t nitems_max, ptrdiff_t item_size)
|
||||
{
|
||||
ptrdiff_t nitems_new = *nitems;
|
||||
ptrdiff_t nbytes = xpalloc_nbytes (pa, &nitems_new, nitems_incr_min,
|
||||
nitems_max, item_size);
|
||||
pa = xrealloc (pa, nbytes);
|
||||
*nitems = nitems_new;
|
||||
return pa;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5903,6 +5903,7 @@ extern void *xnmalloc (ptrdiff_t, ptrdiff_t)
|
|||
ATTRIBUTE_MALLOC_SIZE ((1,2)) ATTRIBUTE_RETURNS_NONNULL;
|
||||
extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t)
|
||||
ATTRIBUTE_ALLOC_SIZE ((2,3)) ATTRIBUTE_RETURNS_NONNULL;
|
||||
extern ptrdiff_t xpalloc_nbytes (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t);
|
||||
extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t)
|
||||
ATTRIBUTE_RETURNS_NONNULL;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue