regexps.com
The programming interfaces described in this chapter provide
some frequently needed functionality built on top of the standard
functions malloc
, realloc
, and free
.
There are functions that work like malloc
 and friends, but
that cause the process to exit with an error message and a 
non-0 status if an allocation fails.  See Allocate or Die.
There are functions that let you keep track of how much memory is used by a particular subsystem of your program, and limit that amount of memory if you choose. You can use these functions to trigger various forms of garbage collection. See Allocation With Limitations.
Finally, There are functions that operate on arrays of bytes.
These do little more than replace standard functions such as
memcpy
, but are included for symmetry and completeness.  See
Array-of-Byte Functions.
#include <hackerlab/mem/must-malloc.h>
The functions in this section allocate memory.  If an allocation
fails, they call panic
 rather than returning.  Thus, these
functions may be used without checking for errors.
void * must_calloc (size_t amt);
Return a newly allocated block large enough to hold amt
 bytes.
If no such block can be allocated, exit by calling panic
.
Fill the newly allocated memory with 0
 bytes.
void * must_malloc (size_t amt);
Return a newly malloced block large enough to hold amt
 bytes.  If
no such block can be allocated, exit by calling panic
.
void * must_realloc (void * ptr, size_t amt);
Return a malloced block large enough to hold amt
 bytes.  If ptr
is not 0
, it should point to a previously malloced block.  The
contents of the new block are initialized from the contents of
ptr
.  If the new block is not the same as ptr
, ptr
 is freed.
If no block can be allocated, exit by calling panic
.
void must_free (void * ptr);
Free a block allocated by must_calloc
, must_malloc
, or
must_realloc
.
#include <hackerlab/mem/alloc-limits.h>
In some situations it is desriable for a subsystem of a program
to limit its use of memory, independently of the rest of the program.
The alloc_limits
 functions are for such situations.
There are two steps to using the alloc_limits
 functions.  First,
you create an alloc_limits
 object which specifies how much memory
your subsystem should, ideally, use, and how much it is permitted to use.
See make_alloc_limits.  Second, use functions like lim_malloc
 
and lim_free
 instead of functions like malloc
 and free
 in the
subsystem to which the limits apply.
An object of the opaque type alloc_limits
 records the rules which
limit memory use in a particular subsystem.
alloc_limits make_alloc_limits (t_uchar * name,
                                size_t threshold,
                                size_t failure_pt,
                                int panic_on_failure,
                                lim_free_memory_fn free_memory,
                                void * closure);
Create a new alloc_limits
 object.
name
 is the name of the subsystem to which these allocation limits
apply.  The name is useful for debugging purposes.
threshold
 specifies an ideal limit on the amount of memory used
by your subsystem.  If a subsystem attempts to allocate more than 
threshold
 bytes, the free_memory
 function for that subsystem
is invoked (see below).  threshold
 may be 0
, in which case the
free_memory
 function is never invoked.
failure_pt
 specifies an absolute limit on the amount of memory
used by your subsystem.  Allocations beyond failure_pt
 fail
(return 0
).
panic_on_failure
, if non-0, means that if the failure point is
reached, or allocation fails, the program will exit with a
message to the standard error stream and a non-0 status.
If 0
, allocation failures return 0
.
free_memory
 is a function pointer:
     typedef void (*lim_free_memory_fn)(void * closure, 
                                        size_t needed);
It is called immediately before an allocation that would exceed
threshold
 (if threshold
 is not 0
).  closure
 is as passed
to make_alloc_limits
 (see below).  needed
 is the number of 
bytes by which the proposed allocation causes the total amount of
memory used by the subsystem to exceed threshold
.  It is completely
safe to call lim_free
 from your free_memory
 function.  It
is possible to call lim_malloc
 or lim_realloc
, but if your
program does this, free_memory
 must be reentrant.
closure
 is an opaque value passed to free_memory
.
If a new alloc_limits
 object can not be allocated, this function
calls panic
 and does not return.
As an alternative to calling make_alloc_limits
 in some situations,
three pre-defined allocation limits are declared in alloc-limits.h
:
     extern alloc_limits lim_use_malloc;
     extern alloc_limits lim_use_must_malloc;
     extern alloc_limits lim_no_allocations;
Allocations performed with lim_use_malloc
 are unlimited and are
effectively like allocations performed with malloc
 or realloc
.
Failed allocations return 0
.
Allocations performed with lim_use_must_malloc
 are unlimited and
are effectively like allocations performed with must_malloc
 or
must_realloc
.  Failed allocations cause the process to exit with
a non-0 status.
Allocations performed with lim_no_allocations
 always fail and return
0
.  lim_free
 has no effect when passed lim_no_allocations
.
void free_alloc_limits (alloc_limits limits);
Free an allocation limits object.
size_t lim_set_threshold (alloc_limits it, size_t threshold);
Modify the threshold
 of an alloc_limits
 object.  Return
the old threshold
.
This function does not immediately call free_memory
, even if
the total amount of memory allocated exceeds the new threshold
.
size_t lim_threshold (alloc_limits limits);
Return the current threshold
 of allocation limits limits
.
size_t lim_set_failure_pt (alloc_limits limits, size_t failure_pt);
Modify the failure_pt
 of an alloc_limits
 object.  Return
the old failure_pt
.
size_t lim_failure_pt (alloc_limits limits);
Return the failure_pt
 of allocation limits limits
.
Function 
lim_is_panic_on_failure
int lim_is_panic_on_failure (alloc_limits limits);
Return the value of the panic_on_failure
 flag of
allocation limits limits
.
Function 
lim_set_panic_on_failure
int lim_set_panic_on_failure (alloc_limits limits, int value);
Set the panic_on_failure
 flag of allocation limits limits
.
Return the old value.
size_t lim_in_use (alloc_limits limits);
Return the amount (in bytes) of memory allocation charged
to limits
 and not yet freed.
size_t lim_high_water_mark (alloc_limits limits);
Return the largest amount (in bytes) of outstanding memory 
allocation charged to limits
 during the lifetime of the process.
These functions allocate and free memory, similarly to 
malloc
, realloc
, and free
, but with allocation limits.
void * lim_malloc (alloc_limits limits, size_t amt);
Allocate amt
 bytes of memory.
If the allocation would exceed the threshold of limits
,
invoke the free_memory
 function first.
If the allocation would exceed the failure_pt
 of limits
, or if
the underlying malloc
 fails, return 0
 (if the panic_on_failure
flag of limits
 is 0
) or exit the process with a non-0 status (if
panic_on_failure
 is non-0).
Adjust the in_use
 and high_water_mark
 of limits
.
If limits
 is 0
, this function works like must_malloc.
void * lim_zalloc (alloc_limits limits, size_t amt);
Use lim_malloc
 to attempt to allocate amt
 bytes
of memory.   If allocation succeeds, initialize that
memory to all zero bytes.
Return the allocated region or 0
 if allocation fails.
void * lim_soft_malloc (alloc_limits limits, size_t amt);
Allocate amt
 bytes of memory.  Return the newly allocated memory.
If the allocation would exceed the failure_pt
 of limits
,
or if the underlying malloc
 fails, return 0
 (if the
panic_on_failure
 flag of limits
 is 0
) or exit the
process with a non-0 status.
Adjust the in_use
 and high_water_mark
 of limits
.
This function does not invoke the free_memory
 function of
limits
, even if the allocation would exceed the threshold of
limits
.
If limits
 is 0
, this function works like must_malloc.
void * lim_realloc (alloc_limits limits, void * prev, size_t amt);
Reallocate prev
 as amt
 bytes of memory.  Copy (up to) amt
 bytes
of data from prev
 to the newly allocated memory.
If the allocation would exceed the threshold of limits
,
invoke the free_memory
 function first.
If the allocation would exceed the failure_pt
 of limits
,
or if the underlying malloc
 fails, return 0
 (if the
panic_on_failure
 flag of limits
 is 0
) or exit the
process with a non-0 status.
Adjust the in_use
 and high_water_mark
 of limits
.
If prev
 is 0
, this function behaves like lim_malloc
.
If limits
 is 0
, this function works like must_realloc.
void * lim_soft_realloc (alloc_limits limits,
                         void * prev,
                         size_t amt);
Reallocate prev
 as amt
 bytes of memory.  Copy (up to) amt
 bytes
of data from prev
 to the newly allocated memory.
If the allocation would exceed the failure_pt
 of limits
, or if
the underlying malloc
 fails, return 0
 (if the
panic_on_failure
 flag of limits
 is 0
) or exit the
process with a non-0 status.
Adjust the in_use
 and high_water_mark
 of limits
.
This function does not invoke the free_memory
 function of
limits
, even if the allocation would exceed the threshold of
limits
.
If limits
 is 0
, this function works like must_realloc.
void lim_free (alloc_limits limits, void * ptr);
Free ptr
.  Adjust the in_use
 and high_water_mark
 values
of limits
.
If limits
 is 0
, this function works like must_free.
int lim_prepare (alloc_limits limits, size_t amt);
Prepare for an allocation of amt
 bytes.
If such an allocation would exceed the threshold of limits
,
invoke the free_memory
 function first.
If the allocation would exceed the failure_pt
 of limits
,
return -1
.  Otherwise, return 0
.
If limits
 is 0
, this function simply returns 0
.
#include <hackerlab/mem/mem.h>
These functions operate on regions of memory as arrays of unsigned bytes with no further interpretation.
void mem_set (t_uchar * mem, unsigned int c, size_t size);
Store size
 bytes of value c
 beginning at mem
.
void mem_set0 (t_uchar * mem, size_t n);
Store n
 0
 bytes beginning at mem
.
void mem_move (t_uchar * to, const t_uchar * from, size_t amt);
Copy amt
 bytes from from
 to to
.  The source and destination
regions may overlap.
int mem_cmp (const t_uchar * m1, const t_uchar * m2, size_t amt);
Compare amt
 bytes starting at m1
 and m2
.  If a difference is
found, immediately return -1
 if the differing byte in m1
 is less
than the byte in m2
, 1
 otherwise.  If no difference is found,
return 0
.
size_t mem_occurrences (const t_uchar * mem,
                        unsigned int c,
                        size_t size);
Search size
 bytes of data for occurences of byte c
 beginning at
mem
.  Return the number of occurences found.
regexps.com