6.7.3 Heap allocation

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 allocates 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