# linalloc (Linear Allocator)
[](https://github.com/qaijuang/linalloc/actions/workflows/miri.yml)
[](https://github.com/qaijuang/linalloc/blob/main/LICENSE)
Small, fixed-capacity arena allocators for single-threaded Rust programs.
You pick the capacity up front. The arena never grows.
Addresses stay stable. When it is full, allocation returns `None`.
## Choose an arena
| `BumpArena` | default | Raw byte allocation from a fixed heap buffer | Values must be dropped by the caller |
| `TypedArena<T>` | default | Values of one type from a fixed heap buffer | Drops live values in reverse allocation order |
| `BumpArenaLazy` | `lazy` | Raw byte allocation from reserved virtual memory | Values must be dropped by the caller |
| `TypedArenaLazy<T>` | `lazy` | Values of one type from reserved virtual memory | Drops live values in reverse allocation order |
All arenas are `!Send` and `!Sync`. They are deliberately single-threaded.
## Use a bump arena
`BumpArena` gives you uninitialized bytes. You choose the layout, initialize
the memory, and drop any values you place there.
```rust
use core::alloc::Layout;
use linalloc::BumpArena;
let arena = BumpArena::new(128);
let slot = arena.alloc_uninit_slice(Layout::new::<u64>()).unwrap();
let ptr = slot.as_mut_ptr().cast::<u64>();
unsafe { ptr.write(42) };
assert_eq!(unsafe { *ptr }, 42);
```
## Use a typed arena
`TypedArena<T>` stores initialized `T` values and drops the live values when
the arena is reset or dropped.
```rust
use linalloc::TypedArena;
let arena = TypedArena::<String>::new(4);
let value = arena.alloc_raw("hello".to_owned()).unwrap();
value.push_str(" world");
assert_eq!(value, "hello world");
```
The borrow checker prevents resetting a typed arena while references into it
are still live:
```rust,compile_fail
use linalloc::TypedArena;
let mut arena = TypedArena::<String>::new(1);
let value = arena.alloc_raw("held".to_owned()).unwrap();
// ----- immutable borrow occurs here
arena.reset();
//^^^^^^^^^^^^^ mutable borrow occurs here
drop(value);
// ----- immutable borrow later used here
```
## Use lazy arenas
Enable `lazy` when you want to reserve a large virtual address range and
commit physical memory only as allocation advances:
```toml
[dependencies]
linalloc = { version = "1.0", features = ["lazy"] }
```
The lazy feature is supported on Unix and Windows targets.
## Safety
Untyped arenas hand you uninitialized bytes. Do not read them until you have
written them. Values stored in untyped arenas are not dropped automatically.
Typed arenas own initialized values. `reset` takes `&mut self`, drops live
values in reverse allocation order, and then reuses the storage.
For untyped arenas, `reset` is unsafe. All returned slices must be dead, and
any values stored in the arena must already have been dropped.
## Miri
Miri covers the default eager arenas.
The lazy arenas use platform virtual-memory calls. Miri does not currently
support every protection mode used by that path.