mirror of
https://github.com/openharmony/third_party_gettext.git
synced 2026-07-01 10:25:03 -04:00
xalloc: Add x2realloc function, from gnulib.
* gnulib-local/lib/xalloc.h (x2realloc): New declaration, from gnulib/lib/xalloc.h. * gnulib-local/lib/xmalloc.c (x2nrealloc): New function, from gnulib/lib/xalloc.h. (x2realloc): New function, from gnulib/lib/xmalloc.c. * gnulib-local/modules/xalloc (configure.ac): Require AC_C_INLINE.
This commit is contained in:
@@ -58,6 +58,22 @@ template <typename T>
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* If P is null, allocate a block of at least *PN bytes; otherwise,
|
||||
reallocate P so that it contains more than *PN bytes. *PN must be
|
||||
nonzero unless P is null. Set *PN to the new block's size, and
|
||||
return the pointer to the new block. *PN is never set to zero, and
|
||||
the returned pointer is never null. */
|
||||
extern void *x2realloc (void *ptr, size_t *pn);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
template <typename T>
|
||||
inline T * x2realloc (T * ptr, size_t *pn)
|
||||
{
|
||||
return (T *) x2realloc ((void *) ptr, pn);
|
||||
}
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* This function is always triggered when memory is exhausted. It is
|
||||
in charge of honoring the three previous items. This is the
|
||||
function to call when one wants the program to die because of a
|
||||
|
||||
@@ -127,3 +127,106 @@ xrealloc (void *p, size_t n)
|
||||
p = fixup_null_alloc (n);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* If P is null, allocate a block of at least *PN such objects;
|
||||
otherwise, reallocate P so that it contains more than *PN objects
|
||||
each of S bytes. S must be nonzero. Set *PN to the new number of
|
||||
objects, and return the pointer to the new block. *PN is never set
|
||||
to zero, and the returned pointer is never null.
|
||||
|
||||
Repeated reallocations are guaranteed to make progress, either by
|
||||
allocating an initial block with a nonzero size, or by allocating a
|
||||
larger block.
|
||||
|
||||
In the following implementation, nonzero sizes are increased by a
|
||||
factor of approximately 1.5 so that repeated reallocations have
|
||||
O(N) overall cost rather than O(N**2) cost, but the
|
||||
specification for this function does not guarantee that rate.
|
||||
|
||||
Here is an example of use:
|
||||
|
||||
int *p = NULL;
|
||||
size_t used = 0;
|
||||
size_t allocated = 0;
|
||||
|
||||
void
|
||||
append_int (int value)
|
||||
{
|
||||
if (used == allocated)
|
||||
p = x2nrealloc (p, &allocated, sizeof *p);
|
||||
p[used++] = value;
|
||||
}
|
||||
|
||||
This causes x2nrealloc to allocate a block of some nonzero size the
|
||||
first time it is called.
|
||||
|
||||
To have finer-grained control over the initial size, set *PN to a
|
||||
nonzero value before calling this function with P == NULL. For
|
||||
example:
|
||||
|
||||
int *p = NULL;
|
||||
size_t used = 0;
|
||||
size_t allocated = 0;
|
||||
size_t allocated1 = 1000;
|
||||
|
||||
void
|
||||
append_int (int value)
|
||||
{
|
||||
if (used == allocated)
|
||||
{
|
||||
p = x2nrealloc (p, &allocated1, sizeof *p);
|
||||
allocated = allocated1;
|
||||
}
|
||||
p[used++] = value;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
static inline void *
|
||||
x2nrealloc (void *p, size_t *pn, size_t s)
|
||||
{
|
||||
size_t n = *pn;
|
||||
|
||||
if (! p)
|
||||
{
|
||||
if (! n)
|
||||
{
|
||||
/* The approximate size to use for initial small allocation
|
||||
requests, when the invoking code specifies an old size of
|
||||
zero. This is the largest "small" request for the GNU C
|
||||
library malloc. */
|
||||
enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
|
||||
|
||||
n = DEFAULT_MXFAST / s;
|
||||
n += !n;
|
||||
}
|
||||
if (xalloc_oversized (n, s))
|
||||
xalloc_die ();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set N = floor (1.5 * N) + 1 so that progress is made even if N == 0.
|
||||
Check for overflow, so that N * S stays in both ptrdiff_t and
|
||||
size_t range. The check may be slightly conservative, but an
|
||||
exact check isn't worth the trouble. */
|
||||
if ((PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX) / 3 * 2 / s
|
||||
<= n)
|
||||
xalloc_die ();
|
||||
n += n / 2 + 1;
|
||||
}
|
||||
|
||||
*pn = n;
|
||||
return xrealloc (p, n * s);
|
||||
}
|
||||
|
||||
/* If P is null, allocate a block of at least *PN bytes; otherwise,
|
||||
reallocate P so that it contains more than *PN bytes. *PN must be
|
||||
nonzero unless P is null. Set *PN to the new block's size, and
|
||||
return the pointer to the new block. *PN is never set to zero, and
|
||||
the returned pointer is never null. */
|
||||
|
||||
void *
|
||||
x2realloc (void *p, size_t *pn)
|
||||
{
|
||||
return x2nrealloc (p, pn, 1);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ stdlib
|
||||
xalloc-oversized
|
||||
|
||||
configure.ac:
|
||||
AC_REQUIRE([AC_C_INLINE])
|
||||
|
||||
Makefile.am:
|
||||
lib_SOURCES += xalloc.h xmalloc.c xstrdup.c
|
||||
|
||||
Reference in New Issue
Block a user