ref: d0ffb958c7247028223c7e53253249d52a47a324
dir: /doc/api/libstd/alloc.txt/
{ title: Allocation description: libstd: Allocation } 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: ```{runmyr mk-example} use std type mytype = a : int b : char c : byte[:[ ;; const main = { var v v = std.mk([ .a = 123 .b = 'x' .c = "my string" /* this isn't heapified */ ]) std.free(v) } ``` ### Alloc and Zalloc `alloc` and `zalloc` know the type that they're being assigned to, and use this to calulate the size to allocate: ```{runmyr mk-example} use std const main = { var x : int# var y : int# x = std.alloc() y = std.zalloc() std.free(x) std.free(y) } ``` ### 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. ```{runmyr mk-example} use std const main = { var x : int[:] x = std.slalloc(10) /* slice of 10 ints */ std.slfree(x) } ``` Growing slices can be done using slgrow() and slzgrow(): ```{runmyr mk-example} use std const main = { var x : int[:] x = std.slalloc(10) /* slice of 10 ints */ x = std.slzgrow(x, 20) /* x[10:20] are guaranteed to be zeroed.*/ std.slfree(x) } ```