allocator
import std::alloc::allocator; · source
Types
The Allocator trait
type trait Allocator {
allocate(mut &this, layout: Layout) -> Result<NonNull<u8>, AllocError>;
deallocate(mut &this, ptr: NonNull<u8>, layout: Layout) -> void;
reallocate(mut &this, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout) -> Result<NonNull<u8>, AllocError>;
}
allocate returns uninitialized memory — write before you read. deallocate requires that the pointer came from a previous allocate on this allocator with a matching layout.
reallocate has a default: allocate, copy, free. An allocator that can grow a block in place should override it.
Collections take A: Allocator as a type parameter, so the storage strategy stays a caller decision instead of being baked into the container.
Methods
allocate(mut &this, layout: Layout) -> Result<NonNull<u8>, AllocError>;
allocate(mut &this, layout: Layout) -> Result<NonNull<u8>, AllocError>;Return a pointer to at least layout.size bytes aligned to layout.alignment. The returned memory is uninitialized; the caller writes to it before any read.
deallocate(mut &this, ptr: NonNull<u8>, layout: Layout) -> void;
deallocate(mut &this, ptr: NonNull<u8>, layout: Layout) -> void;Return memory to the allocator. ptr must have come from a previous allocate on this allocator with a matching layout. Using the pointer after this call is undefined.
reallocate(mut &this, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout) -> Result<NonNull<u8>, AllocError>;
reallocate(mut &this, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout) -> Result<NonNull<u8>, AllocError>;Default implementation: allocate fresh memory, copy, free old. Allocators that can grow a block in place (real realloc) should override for the win.
Implementors
implement trait Allocator for struct GlobalAlloc
implement trait Allocator for struct Arena
std::alloc::arena_alloc
implement trait Allocator for struct Pool
std::alloc::pool
AllocError
type struct AllocError {
kind: AllocErrorKind;
layout: Layout;
static new(kind: AllocErrorKind, layout: Layout) -> AllocError;
describe(&this) -> Str;
}
Failures carry both a kind and the layout that was refused, and describe(&this) -> Str gives a short stable message — the same accessor every standard library error type exposes.
Properties
| Property | Type |
|---|---|
kind | AllocErrorKind |
layout | Layout |
Constructors
static new(kind: AllocErrorKind, layout: Layout) -> AllocError;
Methods
describe(&this) -> Str;
describe(&this) -> Str;A short, stable description of what went wrong, as a borrowed Str. The convergent accessor every stdlib error type exposes (describe(&this) -> Str); Display/Debug for AllocError delegate to it. The requested layout remains available as a field. Borrows a static string literal, so the view outlives any AllocError.
AllocErrorKind
type enum AllocErrorKind {
OutOfMemory;
ZeroSized;
Exhausted;
InvalidLayout;
}
Variants
| Variant | Notes |
|---|---|
OutOfMemory | The underlying allocator returned null; the system is out of memory or hit an address-space limit. |
ZeroSized | The allocator refuses zero-sized requests. Callers that want a non-null dangling pointer for a zero-sized type should handle the zero case themselves before calling allocate. |
Exhausted | A bounded allocator (arena, pool) has no room for this request. |
InvalidLayout | The requested layout is incompatible with this allocator (e.g., the size or alignment doesn't match a Pool's fixed slot). The caller passed the wrong allocator for the requested layout. |
Trait implementations
implement trait Display for struct AllocError
std::fmt::display
implement trait Debug for struct AllocError
std::fmt::display
GlobalAlloc
type struct GlobalAlloc {
static new() -> GlobalAlloc;
}
A zero-sized handle to the process-wide allocator; every instance dispatches through the same backend. Construct it with GlobalAlloc::new(). It is the default for every allocator-generic type in the library, which is what keeps the bare Box<T> spelling meaningful everywhere.
The backend is libc malloc by default and the segment heap in alloc::heap under the native_alloc config. Either way, when the compiler driver has published a per-target Arena, GlobalAlloc routes through it for the duration of a build — that is the compiler's own business and is inactive in user programs.
Constructors
static new() -> GlobalAlloc;
Trait implementations
implement trait Allocator for struct GlobalAlloc
Free Functions
function next_capacity(current: u64, required: u64, min_capacity: u64) -> u64;
function next_capacity(current: u64, required: u64, min_capacity: u64) -> u64;Geometric growth-size for a contiguous buffer that must hold at least required slots. Doubles current (seeded by min_capacity so empty-to-nonempty transitions don't start at a single slot) until it reaches required. Once doubling would overflow u64 the curve has hit its ceiling: return exactly required (already known to fit) rather than wrapping to 0 and looping forever. Shared by Array::reserve_grow and RawBuffer::reserve, whose storage layouts differ (ABI-load-bearing) but whose growth curve is identical.
This is the growth policy the containers share. It lives here rather than in collections so an allocator-aware type outside the stdlib can grow its buffers the same way.
public function alloc(size: u64, align: u64) -> void*;
public function alloc(size: u64, align: u64) -> void*;Allocate size bytes aligned to align via GlobalAlloc. Null/zero guarded; returns null on OOM so the emitter's existing null-check on the old malloc result is unchanged.
public function free(ptr: void*, align: u64) -> void;
public function free(ptr: void*, align: u64) -> void;Free a block from alloc via GlobalAlloc::deallocate, which already no-ops arena-owned pointers (bulk-reclaimed at the target boundary) and frees libc-owned ones. align must match the new site; deallocate ignores the layout size, so a 1-byte placeholder is fine.
The untyped pair new and delete lower to. Both go through GlobalAlloc, so a new T() is placed exactly where a Box or an Array would be. alloc treats a zero size as one byte and a zero alignment as 16, and returns null when the allocation fails rather than aborting. free takes the alignment the block was allocated with.
Constants
const MAX_REALLOC_ALIGN: u64 = 16;type struct Name { ... }
type enum Name { ... }
type trait Name { ... }
type union Name { ... }Begins a type declaration; the keyword that follows says which kind. On its own, type Name = Existing; declares an alias.
type trait Name : Base {
method(&this, other: &This) -> Ret;
}Names a set of methods a type may implement. Inside the body This is the implementing type; methods may carry default bodies, and a trait may require a base trait (type trait Ord : Eq). Generic code asks for a trait with where T: Name.
type trait Allocator {
allocate(mut &this, layout: Layout) -> Result<NonNull<u8>, AllocError>;
deallocate(mut &this, ptr: NonNull<u8>, layout: Layout) -> void;
reallocate(mut &this, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout) -> Result<NonNull<u8>, AllocError>;
}Allocator: the trait every heap strategy implements.
Allocator::allocate(mut &this, layout: Layout) -> Result<NonNull<u8>, AllocError>Return a pointer to at least layout.size bytes aligned to layout.alignment. The returned memory is uninitialized; the caller writes to it before any read.
mut &this
mut &TypeAn exclusive, mutating borrow. As a receiver, mut &this lets the method modify the fields - and callers can see that from the signature alone. As a parameter type, mut &T lets the callee mutate through the reference while the caller keeps ownership.
&this
mut &this
thisThe receiver of a method. Its first parameter declares how the method takes it: &this borrows read-only, mut &this borrows exclusively, and this / mut this move the value in and consume it. In the body, this.field reaches the members.
(parameter) layout: Layouttype struct Layout {
size: u64;
alignment: u64;
}Layout: size + alignment of a memory block.
std::alloc::layouttype struct NonNull<T> {
ptr: T*;
}type struct AllocError {
kind: AllocErrorKind;
layout: Layout;
}Allocator::deallocate(mut &this, ptr: NonNull<u8>, layout: Layout) -> voidReturn memory to the allocator. ptr must have come from a previous allocate on **this** allocator with a matching layout. Using the pointer after this call is undefined.
(parameter) ptr: NonNull<u8>Allocator::reallocate(mut &this, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout) -> Result<NonNull<u8>, AllocError>Default implementation: allocate fresh memory, copy, free old. Allocators that can grow a block in place (real realloc) should override for the win.
(parameter) old_layout: Layout(parameter) new_layout: Layouttype struct Name {
field: Type;
method(&this) -> Ret { ... }
}A value type with named fields and optional methods. Structs live on the stack and are passed by value. Fields are public by default and may carry = default values; methods take their receiver as &this, mut &this, or this.
type struct AllocError {
kind: AllocErrorKind;
layout: Layout;
}AllocError.kind: AllocErrorKindtype enum AllocErrorKind {
OutOfMemory;
ZeroSized;
Exhausted;
InvalidLayout;
}AllocError.layout: Layoutstatic name(param: Type) -> Ret { ... }A method that belongs to the type rather than an instance, called as Type::name(..). For structs, static new(..) returning a struct literal is the idiomatic constructor.
static AllocError::new(kind: AllocErrorKind, layout: Layout) -> AllocError(parameter) kind: AllocErrorKindAllocError::describe(&this) -> StrA short, stable description of what went wrong, as a borrowed Str. The convergent accessor every stdlib error type exposes (describe(&this) -> Str); Display/Debug for AllocError delegate to it. The requested layout remains available as a field.
type struct Str {
bytes: u8*;
length: u64;
}Str: a borrowed UTF-8 string slice.
std::collections::strtype enum Name {
Unit,
Payload(T),
Named { x: i32 },
}An algebraic data type. Variants may be bare or carry a tuple or struct payload, and a match on an enum must cover every variant. Name::Variant names a variant; methods are added with implement enum Name { ... }.
type enum AllocErrorKind {
OutOfMemory;
ZeroSized;
Exhausted;
InvalidLayout;
}AllocErrorKind::OutOfMemoryThe underlying allocator returned null; the system is out of memory or hit an address-space limit.
AllocErrorKind::ZeroSizedThe allocator refuses zero-sized requests. Callers that want a non-null dangling pointer for a zero-sized type should handle the zero case themselves before calling allocate.
AllocErrorKind::ExhaustedA bounded allocator (arena, pool) has no room for this request.
AllocErrorKind::InvalidLayoutThe requested layout is incompatible with this allocator (e.g., the size or alignment doesn't match a Pool's fixed slot). The caller passed the wrong allocator for the requested layout.
type struct GlobalAlloc {}Zero-sized handle to the process-wide allocator. Construct with GlobalAlloc::new(); all instances dispatch through the same underlying backend.
static GlobalAlloc::new() -> GlobalAlloctype struct GlobalAlloc {}Zero-sized handle to the process-wide allocator. Construct with GlobalAlloc::new(); all instances dispatch through the same underlying backend.
const NAME: Type = value;At module level, a true compile-time constant, conventionally SCREAMING_SNAKE_CASE. (mut at module level declares mutable global state instead.)
const MAX_REALLOC_ALIGN: u64 = 16;import a::b;
import a::b::{ X, Y };
import a::b as c;
import a::b::*;Brings a module, or selected items from it, into scope. One path per declaration: use the brace form for several items, as to alias, and * for everything public (prefer the brace form; wildcards invite name collisions).
Allocator::allocate(mut &this, layout: Layout) -> Result<NonNull<u8>, AllocError>Return a pointer to at least layout.size bytes aligned to layout.alignment. The returned memory is uninitialized; the caller writes to it before any read.
Allocator::deallocate(mut &this, ptr: NonNull<u8>, layout: Layout) -> voidReturn memory to the allocator. ptr must have come from a previous allocate on **this** allocator with a matching layout. Using the pointer after this call is undefined.
Allocator::reallocate(mut &this, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout) -> Result<NonNull<u8>, AllocError>Default implementation: allocate fresh memory, copy, free old. Allocators that can grow a block in place (real realloc) should override for the win.
type trait Allocator {
allocate(mut &this, layout: Layout) -> Result<NonNull<u8>, AllocError>;
deallocate(mut &this, ptr: NonNull<u8>, layout: Layout) -> void;
reallocate(mut &this, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout) -> Result<NonNull<u8>, AllocError>;
}Allocator: the trait every heap strategy implements.
std::alloc::allocatorAllocError.layout: Layoutimplement struct Name { ... }
implement trait Trait for Type { ... }
implement u64 { ... }Adds methods to a type outside its declaration. implement struct T (or enum, or a bare primitive) opens an inherent block; implement trait Tr for T supplies a trait's methods for one type. Resolution is at compile time - no dynamic dispatch.
implement trait Trait for Type { ... }Introduces a trait implementation: the block supplies, for one concrete type, the method bodies the trait requires.
language referenceimplement trait Trait for Type { ... }Names the type a trait implementation is for. The block that follows supplies the bodies the trait requires.
language referencetype struct Arena {
head: Chunk*;
current: Chunk*;
chunk_size: u64;
}Arena: bump allocator with bulk release.
std::alloc::arenatype struct Pool {
slot: Layout;
slots_per_block: u64;
free_list: FreeNode*;
blocks: Block*;
}Pool: O(1) allocator for uniformly-sized slots.
std::alloc::poolAllocError::describe(&this) -> StrA short, stable description of what went wrong, as a borrowed Str. The convergent accessor every stdlib error type exposes (describe(&this) -> Str); Display/Debug for AllocError delegate to it. The requested layout remains available as a field.
AllocError.kind: AllocErrorKindstatic AllocError::new(kind: AllocErrorKind, layout: Layout) -> AllocErrortype trait Display {
fmt<W>(&this, f: mut &Formatter<W>) -> Result<(), FmtError>
where W: FmtWrite;
}Display / Debug / Formatter.
std::fmt::displaytype trait Debug {
fmt<W>(&this, f: mut &Formatter<W>) -> Result<(), FmtError>
where W: FmtWrite;
}AllocErrorKind::OutOfMemoryThe underlying allocator returned null; the system is out of memory or hit an address-space limit.
std::alloc::allocatorAllocErrorKind::ZeroSizedThe allocator refuses zero-sized requests. Callers that want a non-null dangling pointer for a zero-sized type should handle the zero case themselves before calling allocate.
AllocErrorKind::ExhaustedA bounded allocator (arena, pool) has no room for this request.
std::alloc::allocatorAllocErrorKind::InvalidLayoutThe requested layout is incompatible with this allocator (e.g., the size or alignment doesn't match a Pool's fixed slot). The caller passed the wrong allocator for the requested layout.
std::alloc::allocatorstatic GlobalAlloc::new() -> GlobalAlloctype struct Box<T, A = GlobalAlloc> where A: Allocator {
ptr: T*;
alloc: A;
}Box<T, A>: single-owner heap allocation.
std::alloc::boxintrinsic function malloc(size: u64) -> void*namespace std::alloc::heap;heap: the mmap-backed process heap (Low-Level Plan Stage 3).
function name<T>(param: Type) -> Ret { ... }Declares a function. Parameters are written name: Type and are never inferred; the return type follows -> and defaults to void. Declaration order does not matter: every signature is collected before any body is checked, so functions may call each other freely and recurse.
function next_capacity(current: u64, required: u64, min_capacity: u64) -> u64Geometric growth-size for a contiguous buffer that must hold at least required slots. Doubles current (seeded by min_capacity so empty-to-nonempty transitions don't start at a single slot) until it reaches required.
(parameter) current: u64(parameter) required: u64(parameter) min_capacity: u64type struct Array<T, A = GlobalAlloc> where A: Allocator {
ptr: T*;
length: i64;
capacity: i64;
alloc: A;
}Array<T, A>: growable, heap-backed, contiguous sequence.
std::collections::arraytype struct RawBuffer<T, A = GlobalAlloc> where A: Allocator {
ptr: T*;
capacity: u64;
alloc: A;
}RawBuffer: the allocator-backed storage half of a growable container.
std::collections::raw_bufferRawBuffer::reserve(mut &this, used: u64, additional: u64, min_capacity: u64) -> Result<(), AllocError>Ensure at least additional more slots past used fit. Over-allocates along the doubling curve, seeded by min_capacity when the buffer is small (so empty-to-nonempty transitions don't start at a single slot).
public function name() { ... }
public:Visible to any module that imports this one - the default for top-level items and for struct fields, so it is mostly written to be explicit. public: opens a visibility block that groups the members after it.
public function alloc(size: u64, align: u64) -> void*Allocate size bytes aligned to align via GlobalAlloc. Null/zero guarded; returns null on OOM so the emitter's existing null-check on the old malloc result is unchanged.
(parameter) size: u64(parameter) align: u64public function free(ptr: void*, align: u64) -> voidFree a block from alloc via GlobalAlloc::deallocate, which already no-ops arena-owned pointers (bulk-reclaimed at the target boundary) and frees libc-owned ones. align must match the new site; deallocate ignores the layout size, so a 1-byte placeholder is fine.
(parameter) ptr: void*public function alloc(size: u64, align: u64) -> void*Allocate size bytes aligned to align via GlobalAlloc. Null/zero guarded; returns null on OOM so the emitter's existing null-check on the old malloc result is unchanged.
GlobalAlloc::deallocate(mut &this, ptr: NonNull<u8>, layout: Layout) -> voidvia trait Allocator
std::alloc::allocatornew T { field: value }
new E::Variant(args)
new T[n]Heap allocation. new T { .. } places a struct literal on the heap and yields a T*, and new E::V(args) does the same for an enum variant; new T[n] reserves n uninitialised T - the typed malloc. The storage comes from T's Allocate implementation, or else the global allocator. Parentheses after a struct's name are refused (E0117): there are no constructors, and a struct's static new(..) is an ordinary method.
delete p;Releases what new T { .. } allocated: the pointee's Drop and the values its fields own, then its storage, through T's Allocate::release. Memory from new T[n] or malloc is released with free instead.
public function free(ptr: void*, align: u64) -> voidFree a block from alloc via GlobalAlloc::deallocate, which already no-ops arena-owned pointers (bulk-reclaimed at the target boundary) and frees libc-owned ones. align must match the new site; deallocate ignores the layout size, so a 1-byte placeholder is fine.