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():