Allocation
Stack allocation
Local variables, fixed-size arrays, array literals and structs live on the stack:
fn compute() {
var buffer: [1024]u8; // stack-allocated (zeroed)
let items = [1, 2, 3, 4, 5]; // stack-allocated
var point: Vec2; // stack-allocated (zeroed struct)
let p = Person { name: "Alice"; age: 30; }; // stack-allocated
}Stack space is reserved in the function prologue. No allocation call is needed. A struct is plain bytes held inline wherever it is stored (a local, a field, an array element); returning one copies it to the caller.
Heap allocation
Component instances are heap-allocated:
let app = Counter {}; // heap-allocated (component)The managed parts of a value (a computed string’s buffer, a container’s elements) live on the heap too, owned by the value; see Ownership.
The mem module
For manual heap allocation, import the mem module:
import mem from "mem";
let data: *u8 = mem.alloc(size) or return; // MemError.OutOfMemory passes on
defer mem.free(data, size);| Function | Signature | Description |
|---|---|---|
alloc | (size: i64) -> *u8 or MemError | Allocate bytes (zeroed); MemError.OutOfMemory when there is no memory |
alloc_or_trap | (size: i64) -> *u8 | The same, stopping the program with trap: out of memory instead |
realloc | (p: *u8, old: i64, new: i64) -> *u8 or MemError | Resize a block (contents kept, p freed) |
free | (ptr: *u8, size: i64) | Free allocation |
heap_arena / free_arena | (size: i64) -> arena.Arena or MemError / (a: *arena.Arena) | An arena over heap memory |
copy_raw, move_raw, set_raw, zero_raw | (dst: *u8, src: *const u8, n: i64), … | The byte operations below with i64 lengths |
copy | (dst: *u8, src: *u8, count: u64) | Copy bytes (non-overlapping) |
move | (dst: *u8, src: *u8, count: u64) | Copy bytes (overlapping safe) |
set | (dst: *u8, val: u8, count: u64) | Fill memory with byte value |
zero | (dst: *u8, count: u64) | Zero-fill memory |
compare | (a: *u8, b: *u8, count: u64) -> i32 | Compare bytes (-1, 0, 1) |
equal | (a: *u8, b: *u8, count: u64) -> bool | Byte equality check |
live_allocs | () -> i64 | Heap blocks currently allocated (strings included) |
Note: mem.free takes the pointer and the block’s size; the size is a hint the runtime may ignore (pass 0 when you don’t know it). See mem.
String allocation
The string type is a 24-byte descriptor (pointer + length + capacity). String operations that produce new values (+, interpolation) heap-allocate internally. The compiler manages string lifetime automatically — see Ownership.
let greeting: string = "Hello, " + name; // heap-allocated result
// freed automatically at scope exitWhere values live
| Value | Location |
|---|---|
Primitives (i64, bool, f64, etc.) | Stack (local slot) |
Fixed arrays ([N]T) | Stack |
Array literals ([1, 2, 3]) | Stack |
Struct locals and literals (Type { ... }) | Stack (inline) |
Component instances (Comp {}) | Heap |
| Strings (dynamic) | Heap (descriptor on stack, data on heap) |
mem.alloc(...) | Heap |
| Slices | Stack (fat pointer: ptr + len) |
Last modified: