Summary: Memory Allocation
pkg std =
generic mk : (val : @a -> @a#)
generic alloc : ( -> @a#)
generic zalloc : ( -> @a#)
generic free : (v:@a# -> void)
generic slalloc : (len : size -> @a[:])
generic slzalloc : (len : size -> @a[:])
generic slgrow : (sl : @a[:]#, len : size -> @a[:])
generic slzgrow : (sl : @a[:]#, len : size -> @a[:])
generic slfree : (sl : @a[:] -> void)
const bytealloc : (sz:size -> byte#)
const zbytealloc : (sz:size -> byte#)
const bytefree : (m:byte#, sz:size -> void)
;;
generic mk : (val : @a -> @a#)
mk creates a shallow copy of variable passed to it on the heap, returning a
pointer to the value that it allocated. It is conventionally used for creating
new copies of larger complex data structures, although it can be used to
heapify any value.
Returns: Pointer to fully initialized value of type '@a', based on the value passed in.
generic alloc : ( -> @a#)
generic zalloc : ( -> @a#)
alloc allocates or free a single element of type @a, respectively. zalloc
does the same, but zeros the memory allocated before returning it. free is
used to return the memory allocated by these functions to the system. In
general, mk is preferred over these functions, as it does not leave any
values uninitialized.,
generic slalloc : (len : size -> @a[:])
generic slzalloc : (len : size -> @a[:])
slalloc allocates or frees a slice of len items of type @a. slzalloc
does the same, but zeros the memory allocated before returning it. slfree
is used to return the memory to the system.
generic slgrow : (sl : @a[:]#, len : size -> @a[:])
generic slzgrow : (sl : @a[:]#, len : size -> @a[:])
slgrow resizes the slize sl to length len, allocating the appropriate
amount of memory. slzgrow does the same, but any elements between the old
and new length are zeroed, as in slzalloc.
generic free : (v:@a# -> void)
generic slfree : (sl : @a[:] -> void)
free and slfree free the storage allocated allocated for the value or
slice passed to them , allowing it to be reused again later in the program.
This memory may be unmapped and returned to the operating system, or it may be
cached within the program.
Any uses of memory after a free call is invalid.
const bytealloc : (sz:size -> byte#)
const zbytealloc : (sz:size -> byte#)
const bytefree : (m:byte#, sz:size -> void)
bytealloc bytezalloc, and bytefree are the low level raw-byte allocation
interface, returning blobs of bytes. Since the only way to use more than one
of these bytes is to cast to a different type, the generic versions are
generally a better choice.
Examples
Overall, the examples here should not be unfamiliar to anyone who has used either C or C++.
Mk
std.mk should be used to create new, fully constructed values wherever
possible. The code for this looks like:
Alloc and Zalloc
alloc and zalloc know the type that they're being assigned to, and use
this to calulate the size to allocate:
Slalloc and Slzalloc
slalloc and slzalloc take a size to allocate, but infer the type similar
to alloc and zalloc. They're freed with std.slfree() and slzfree().
Thankfully, unlike C++ delete and delete[], it's impossible to pass a slice
to the wrong free function.
Growing slices can be done using slgrow() and slzgrow():