Heap allocation supports deallocation of allocated memory in any order. Dictionary allocation is not affected by it (i.e., it does not end a contiguous region). In Gforth, these words are implemented using the standard C library calls malloc(), free() and realloc().
The memory region produced by one invocation of allocate
or
resize
is internally contiguous. There is no contiguity between
such a region and any other region (including others allocated from the
heap).
allocate
( u – a_addr wior ) memory “allocate”
Allocate u address units of contiguous data space. The initial contents of the data space is undefined. If the allocation is successful, a-addr is the start address of the allocated region and wior is 0. If the allocation fails, a-addr is undefined and wior is a non-zero I/O result code.
free
( a_addr – wior ) memory “free”
Return the region of data space starting at a-addr to the
system. The region must originally have been obtained using
allocate
or resize
. If the operational is
successful, wior is 0. If the operation fails, wior is
a non-zero I/O result code.
resize
( a_addr1 u – a_addr2 wior ) memory “resize”
Change the size of the allocated area at a-addr1 to u
address units, possibly moving the contents to a different
area. a-addr2 is the address of the resulting area. If the
operation is successful, wior is 0. If the operation
fails, wior is a non-zero I/O result code. If a-addr1
is 0, Gforth’s (but not the Standard) resize
allocate
s u address units.
The following words are useful for dealing with memory blocks:
save-mem
( addr1 u – addr2 u ) gforth-0.2 “save-mem”
Copy a memory block into a newly allocated region in the heap.
free-mem-var
( addr – ) gforth-experimental “free-mem-var”
Addr is the address of a 2variable containing address and size of a memory range; frees memory and clears the 2variable.
extend-mem
( addr1 u1 u – addr addr2 u2 ) gforth-experimental “extend-mem”
Extend memory block addr1 u1 allocated from the heap by u aus. The (possibly reallocated) piece is addr2 u2, the extension is at addr.
The $tring words can also be used for dealing with memory blocks, See $tring words.
For growable memory buffers you can use $trings, or the following
words. Because the allocated memory of a buffer managed with
adjust-buffer
does not shrink, there is no heap-management
overhead when adjusting the buffer for a size smaller than the largest
one seen yet.
buffer%
( u1 u2 – ) gforth-experimental “buffer%”
u1 is the alignment and u2 is the size of a buffer descriptor.
init-buffer
( addr – ) gforth-experimental “init-buffer”
adjust-buffer
( u addr – ) gforth-experimental “adjust-buffer”
Adjust buffer% at addr to length u. This may grow the allocated area, but never shrinks it.
You can get the current address and length of such a buffer with
2@
.
Typical usage:
create mybuf buffer% %size allot mybuf init-buffer s" frobnicate" mybuf adjust-buffer mybuf 2@ move mybuf 2@ type s" foo" mybuf adjust-buffer mybuf 2@ move mybuf 2@ type