The API provides a number of memory allocation functions for
allocating memory that can be passed to gawk
, as well as a number of
convenience macros.
This subsection presents them all as function prototypes, in
the way that extension code would use them:
void *gawk_malloc(size_t size);
Call the correct version of malloc()
to allocate storage that may
be passed to gawk
.
void *gawk_calloc(size_t nmemb, size_t size);
Call the correct version of calloc()
to allocate storage that may
be passed to gawk
.
void *gawk_realloc(void *ptr, size_t size);
Call the correct version of realloc()
to allocate storage that may
be passed to gawk
.
void gawk_free(void *ptr);
Call the correct version of free()
to release storage that was
allocated with gawk_malloc()
, gawk_calloc()
, or gawk_realloc()
.
The API has to provide these functions because it is possible
for an extension to be compiled and linked against a different
version of the C library than was used for the gawk
executable.107 If gawk
were
to use its version of free()
when the memory came from an
unrelated version of malloc()
, unexpected behavior would
likely result.
Three convenience macros may be used for allocating storage
from gawk_malloc()
, gawk_calloc
, and
gawk_realloc()
. If the allocation fails, they cause gawk
to exit with a fatal error message. They should be used as if they were
procedure calls that do not return a value:
#define emalloc(pointer, type, size, message) …
The arguments to this macro are as follows:
pointer
The pointer variable to point at the allocated storage.
type
The type of the pointer variable. This is used to create a cast for
the call to gawk_malloc()
.
size
The total number of bytes to be allocated.
message
A message to be prefixed to the fatal error message. Typically this is the name of the function using the macro.
For example, you might allocate a string value like so:
awk_value_t result; char *message; const char greet[] = "Don't Panic!"; emalloc(message, char *, sizeof(greet), "myfunc"); strcpy(message, greet); make_malloced_string(message, strlen(message), & result);
#define ezalloc(pointer, type, size, message) …
This is like emalloc()
, but it calls gawk_calloc()
instead of gawk_malloc()
.
The arguments are the same as for the emalloc()
macro, but this
macro guarantees that the memory returned is initialized to zero.
#define erealloc(pointer, type, size, message) …
This is like emalloc()
, but it calls gawk_realloc()
instead of gawk_malloc()
.
The arguments are the same as for the emalloc()
macro.
Two additional functions allocate MPFR and GMP objects for use by extension functions that need to create and then return such values.
NOTE: These functions are obsolete. Extension functions that need local MPFR and GMP values should simply allocate them on the stack and clear them, as any other code would.
The functions are:
void *get_mpfr_ptr();
Allocate and initialize an MPFR object and return a pointer to it.
If the allocation fails, gawk
exits with a fatal
“out of memory” error. If gawk
was compiled without
MPFR support, calling this function causes a fatal error.
void *get_mpz_ptr();
Allocate and initialize a GMP object and return a pointer to it.
If the allocation fails, gawk
exits with a fatal
“out of memory” error. If gawk
was compiled without
MPFR support, calling this function causes a fatal error.
Both of these functions return ‘void *’, since the gawkapi.h
header file should not have dependency upon <mpfr.h>
(and <gmp.h>
,
which is included from <mpfr.h>
). The actual return values are of
types mpfr_ptr
and mpz_ptr
respectively, and you should cast
the return values appropriately before assigning the results to variables
of the correct types.
The memory allocated by these functions should be freed with
gawk_free()
.
This is more common on MS-Windows systems, but it can happen on Unix-like systems as well.