Standard library · System and tools

mem

Working with memory directly: allocating and freeing, copying, arenas and pools, and leak checking.

import mem
On this page
  1. Types
  2. Functions

Most programs never need this package: vectors, maps and strings look after their own memory. The mem package is for low-level work, such as talking to a C library or building a data structure of your own. Everything you take with Allocate has to be given back with Free.

An arena is one large block you take pieces off the front of and then release all at once; it is very fast for work with many small objects that share a lifetime. A pool hands out and takes back blocks of one fixed size.

Types

Arena

struct Arena
A memory arena.
NameTypeDescription
bufvoid*The address of the arena's memory.
capu64 = 0The capacity in bytes.
usedu64 = 0How much has been taken.
mem-Arena.salam
import mem

func main:
    mut arena := mem.NewArena(1024 as u64)
    println mem.ArenaCapacity(arena), mem.ArenaUsed(arena)
    a := mem.ArenaAlloc(arena, 100 as u64)
    b := mem.ArenaAllocZeroed(arena, 200 as u64)
    println a != null, b != null, mem.ArenaUsed(arena) >= 300, mem.ArenaRemaining(arena) <= 724
    println mem.ArenaAlloc(arena, 4000 as u64) == null
    mem.ArenaReset(arena)
    println mem.ArenaUsed(arena), arena.cap
    mem.ArenaFree(arena)
end
Output1024 0 true true true true true 0 1024

Pool

struct Pool
A pool of equally sized blocks.
NameTypeDescription
block_sizeu64 = 0The size of each block.
block_countu64 = 0The number of blocks.
blocksvoid*The address of the blocks' memory.
free_listvoid*The list of free blocks.
mem-Pool.salam
import mem

func main:
    mut pool := mem.NewPool(32 as u64, 4 as u64)
    println mem.PoolBlockSize(pool), mem.PoolCapacity(pool)
    b1 := mem.PoolAlloc(pool)
    b2 := mem.PoolAlloc(pool)
    println b1 != null, b2 != null, b1 != b2
    mem.PoolFree(pool, b1)
    b3 := mem.PoolAlloc(pool)
    println b3 == b1
    mem.PoolDestroy(pool)
end
Output32 4 true true true true

Functions

NewArena

func NewArena(capacity: u64): Arena
Builds an arena of the given capacity.

The example for this item is shown with the ones above: mem-Arena.salam

ArenaAlloc

func ArenaAlloc(a &: Arena, size: u64): void*
Takes memory off the arena; the size is rounded up to a multiple of eight. It returns null when there is no room, or when the size is zero.

The example for this item is shown with the ones above: mem-Arena.salam

ArenaAllocZeroed

func ArenaAllocZeroed(a &: Arena, size: u64): void*
Like ArenaAlloc, with the memory zeroed.

The example for this item is shown with the ones above: mem-Arena.salam

ArenaReset

func ArenaReset(a &: Arena)
Takes back everything at once so the arena can be used again.

The example for this item is shown with the ones above: mem-Arena.salam

ArenaFree

func ArenaFree(a &: Arena)
Releases the arena's memory.

The example for this item is shown with the ones above: mem-Arena.salam

ArenaUsed

func ArenaUsed(a &: Arena): u64
The bytes taken so far.

The example for this item is shown with the ones above: mem-Arena.salam

ArenaCapacity

func ArenaCapacity(a &: Arena): u64
The arena's capacity.

The example for this item is shown with the ones above: mem-Arena.salam

ArenaRemaining

func ArenaRemaining(a &: Arena): u64
The bytes left.

The example for this item is shown with the ones above: mem-Arena.salam

NewPool

func NewPool(block_size: u64, block_count: u64): Pool
Builds a pool with the given number and size of blocks.

The example for this item is shown with the ones above: mem-Pool.salam

PoolAlloc

func PoolAlloc(p &: Pool): void*
Hands out a free block, or null when none is left.

The example for this item is shown with the ones above: mem-Pool.salam

PoolFree

func PoolFree(p &: Pool, ptr: void*)
Gives a block back to the pool; the next allocation hands out the same one.

The example for this item is shown with the ones above: mem-Pool.salam

PoolBlockSize

func PoolBlockSize(p &: Pool): u64
The block size.

The example for this item is shown with the ones above: mem-Pool.salam

PoolCapacity

func PoolCapacity(p &: Pool): u64
The total number of blocks.

The example for this item is shown with the ones above: mem-Pool.salam

PoolDestroy

func PoolDestroy(p &: Pool)
Releases the pool's memory.

The example for this item is shown with the ones above: mem-Pool.salam

Allocate

func Allocate(size: u64): void*
Takes a piece of memory of the given size; its contents are undefined.
mem-Allocate.salam
import mem

func main:
    b := mem.Allocate(8 as u64)
    mem.Set(b, 0, 8 as u64)
    bytes := b as i8*
    bytes[0] = 65 as i8
    bytes[1] = 66 as i8
    b2 := mem.AllocateZeroed(8 as u64)
    mem.Copy(b2, b, 2 as u64)
    bytes2 := b2 as i8*
    println bytes2[0], bytes2[1], bytes2[2]
    mem.MemMove(b, (b as i64 + 1) as void*, 1 as u64)
    println bytes[0]
    b3 := mem.Reallocate(b, 64 as u64)
    arr := mem.AllocateArray(4 as u64, 8 as u64)
    arr64 := arr as i64*
    println arr64[3]
    mem.Free(b3)
    mem.Free(b2)
    mem.Free(arr)
end
Output65 66 0 66 0

Reallocate

func Reallocate(ptr: void*, size: u64): void*
Changes the size of memory already taken and keeps its contents; it may return a new address.

The example for this item is shown with the ones above: mem-Allocate.salam

Free

func Free(ptr: void*)
Gives memory back.

The example for this item is shown with the ones above: mem-Allocate.salam

Set

func Set(ptr: void*, value: int, n: u64)
Fills n bytes with the given value.

The example for this item is shown with the ones above: mem-Allocate.salam

Copy

func Copy(dst: void*, src: void*, n: u64)
Copies n bytes; the two ranges must not overlap.

The example for this item is shown with the ones above: mem-Allocate.salam

MemMove

func MemMove(dst: void*, src: void*, n: u64): void*
Like Copy, but correct even when the ranges overlap.

The example for this item is shown with the ones above: mem-Allocate.salam

AllocateZeroed

func AllocateZeroed(size: u64): void*
Takes zeroed memory.

The example for this item is shown with the ones above: mem-Allocate.salam

AllocateArray

func AllocateArray(count: u64, size: u64): void*
Takes zeroed memory for count elements of size bytes each.

The example for this item is shown with the ones above: mem-Allocate.salam

AllocCount

func AllocCount(): i64
The number of allocations; zero unless the program was built with memory debugging.
mem-Debug.salam
import mem

func main:
    println mem.IsMemDebug(), mem.IsAsanActive(), mem.MemDebugActive()
    println mem.AllocCount(), mem.FreeCount(), mem.LiveBytes(), mem.PeakBytes()
    mem.CheckLeaks()
end
Outputfalse false false 0 0 0 0

FreeCount

func FreeCount(): i64
The number of frees; only with memory debugging.

The example for this item is shown with the ones above: mem-Debug.salam

LiveBytes

func LiveBytes(): i64
The bytes taken and not yet given back.

The example for this item is shown with the ones above: mem-Debug.salam

PeakBytes

func PeakBytes(): i64
The most memory held at one moment.

The example for this item is shown with the ones above: mem-Debug.salam

IsMemDebug

func IsMemDebug(): bool
True when the program was built with allocation counting.

The example for this item is shown with the ones above: mem-Debug.salam

IsAsanActive

func IsAsanActive(): bool
True when the program was built with the ASan checker.

The example for this item is shown with the ones above: mem-Debug.salam

MemDebugActive

func MemDebugActive(): bool
True when either memory checker is on.

The example for this item is shown with the ones above: mem-Debug.salam

CheckLeaks

func CheckLeaks()
Reports any memory that was never given back; call it at the end of the program.

The example for this item is shown with the ones above: mem-Debug.salam