Hash :
5d5120d7
Author :
Date :
2021-04-18T20:50:55
safe-alloc: fix pointer implementation The old implementation assumed that all pointers use the same internal representation, but the C standard doesn’t guarantee this. Use void * (pointer) not void ** (pointer-to-pointer) for the internal functions’ API. The internal functions now return NULL if and only if they failed, and the macros translate that into -1 or 0 to satisfy the existing API. * doc/safe-alloc.texi (Safe Allocation Macros): Mention overflow. * lib/safe-alloc.c: Major rewrite. Now this simply defines SAFE_ALLOC_INLINE and includes safe-alloc.h. * lib/safe-alloc.h: Include stddef.h, not stdlib.h. (SAFE_ALLOC_INLINE): New macro; use Gnulib inline function style. (safe_alloc_realloc_n): New API, which passes and returns the pointer, and which returns NULL if and only if failure occurs. (safe_alloc_check): New function. (ALLOC, ALLOC_N, ALLOC_N_UNINITIALIZED, REALLOC_N): Redo using the new API for internal functions, and using calloc which is good enough since it’s GNU-compatible now. (FREE): Expand to an expression rather than merely to something that needs a following ‘;’ to become a statement. * modules/safe-alloc (Depends-on): Add calloc-gnu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
@node Safe Allocation Macros
@section Safe Allocation Macros
The standard C library malloc/realloc/calloc/free APIs are prone to a
number of common coding errors. The @code{safe-alloc} module provides
macros that make it easier to avoid many of them. It still uses the
standard C allocation functions behind the scenes.
Some of the memory allocation mistakes that are commonly made are
@itemize @bullet
@item
passing the incorrect number of bytes to @code{malloc}, especially
when allocating an array,
@item
unchecked integer overflow when calculating array sizes,
@item
fail to check the return value of @code{malloc} and @code{realloc} for
errors,
@item
forget to fully initialize memory just allocated with @code{malloc},
@item
duplicate calls to @code{free} by forgetting to set the pointer
variable to @code{NULL},
@item
leaking memory in calls to @code{realloc} when that call fails.
@end itemize
The @code{safe-alloc} module addresses these problems in the following way:
@itemize @bullet
@item
It defines macros that wrap around the standard C allocation
functions. That makes it possible to use the compiler's knowledge of
the size of objects for allocation; it also allows setting pointers
passed in as arguments when appropriate.
@item
It uses return values only for a success/failure error condition flag,
and annotates them with GCC's @code{__warn_unused_result__} attribute.
@item
When allocating a fresh array, it uses @code{calloc} instead of
@code{malloc} so that the array's contents are zeroed.
However, memory added to an already-existing array is uninitialized.
@end itemize
@defmac {int} ALLOC (ptr)
@findex ALLOC
Allocate @code{sizeof *ptr} bytes of memory and store the address of
allocated memory in @code{ptr}. Fill the newly allocated memory with
zeros.
Returns @minus{}1 on failure, 0 on success.
@end defmac
@defmac {int} ALLOC_N (ptr, count)
@findex ALLOC_N
Allocate an array of @code{count} elements, each @code{sizeof *ptr}
bytes long, and store the address of allocated memory in
@code{ptr}. Fill the newly allocated memory with zeros.
Returns @minus{}1 on failure, 0 on success.
@end defmac
@defmac {int} ALLOC_N_UNINITIALIZED (ptr, count)
@findex ALLOC_N_UNINITIALIZED
Allocate an array of @code{count} elements, each @code{sizeof *ptr}
bytes long, and store the address of allocated memory in
@code{ptr}. The allocated memory is not initialized.
Returns @minus{}1 on failure, 0 on success.
@end defmac
@defmac {int} REALLOC_N (ptr, count)
@findex REALLOC_N
Reallocate the memory pointed to by @code{ptr} to be big enough to hold
at least @code{count} elements, each @code{sizeof *ptr} bytes long,
and store the address of allocated memory in @code{ptr}. If
reallocation fails, the @code{ptr} variable is not modified.
If the new array is smaller than the old one, discard excess contents;
if larger, the newly added storage is not initialized.
Returns @minus{}1 on failure, 0 on success.
@end defmac
@defmac {void} FREE (ptr)
@findex FREE
Free the memory stored in @code{ptr} and set @code{ptr} to
@code{NULL}.
@end defmac