pub unsafe trait Allocator {
// Required methods
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>;
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout);
// Provided methods
fn allocate_zeroed(
&self,
layout: Layout,
) -> Result<NonNull<[u8]>, AllocError> { ... }
unsafe fn grow(
&self,
ptr: NonNull<u8>,
old_layout: Layout,
new_layout: Layout,
) -> Result<NonNull<[u8]>, AllocError> { ... }
unsafe fn grow_zeroed(
&self,
ptr: NonNull<u8>,
old_layout: Layout,
new_layout: Layout,
) -> Result<NonNull<[u8]>, AllocError> { ... }
unsafe fn shrink(
&self,
ptr: NonNull<u8>,
old_layout: Layout,
new_layout: Layout,
) -> Result<NonNull<[u8]>, AllocError> { ... }
fn by_ref(&self) -> &Self
where Self: Sized { ... }
}Expand description
An implementation of Allocator can allocate, grow, shrink, and deallocate
arbitrary blocks of data described via Layout.
Allocator is designed to be implemented on ZSTs, references, or smart
pointers because having an allocator like MyAlloc([u8; N]) cannot be
moved, without updating the pointers to the allocated memory.
Unlike GlobalAlloc, zero-sized allocations are allowed in Allocator.
If an underlying allocator does not support this (like jemalloc) or
return a null pointer (such as libc::malloc), this must be caught by
the implementation.
§Currently allocated memory
Some of the methods require that a memory block be currently allocated via an allocator. This means that:
- The starting address for that memory block was previously returned by
allocate,grow, orshrink, and - The memory block has not been subsequently deallocated, where blocks are
either deallocated directly by being passed to deallocate or were change
by being passed to
groworshrinkthat returnsOk. Ifgroworshrinkhave returnedErr, the passed pointer remains valid.
§Memory fitting
Some of the methods require that a layout fit a memory block. What it means for a layout to “fit” a memory block means (or equivalently, for a memory block to “fit” a layout) is that the following conditions must hold:
- The block must be allocated with the same alignment as
layout.align(), and - The provided
layout.size()must fall in the rangemin..=max, where:minis the size of the layout most recently used to allocate the block, andmaxis the latest actual size returned fromallocate,grow, orshrink.
#Safety
- Memory blocks returned from an allocator must point to valid memory and retain their validity until the instance and all of its clones are dropped,
- Cloning or moving the allocator must not invalidate memory blocks returned from this allocator. A cloned allocator must behave like the same allocator, and
- Any pointer to a memory block which is currently allocated may be passed to any other method of the allocator.
Required Methods§
Sourcefn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>
Try to allocate a slice of memory within this allocator instance, returning the new allocation.
Sourceunsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout)
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout)
Release an allocation produced by this allocator.
§Safety
The value ptr must represent an allocation produced by this allocator, otherwise
a memory access error may occur. The value old_layout must correspond to the
layout produced by the previous allocation.
Provided Methods§
Sourcefn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>
fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>
Try to allocate a slice of memory within this allocator instance, returning the new allocation. The memory will be initialized with zeroes.
Sourceunsafe fn grow(
&self,
ptr: NonNull<u8>,
old_layout: Layout,
new_layout: Layout,
) -> Result<NonNull<[u8]>, AllocError>
unsafe fn grow( &self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError>
Try to extend the size of an allocation to accomodate a new, larger layout.
Sourceunsafe fn grow_zeroed(
&self,
ptr: NonNull<u8>,
old_layout: Layout,
new_layout: Layout,
) -> Result<NonNull<[u8]>, AllocError>
unsafe fn grow_zeroed( &self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError>
Try to extend the size of an allocation to accomodate a new, larger layout. Fill the extra capacity with zeros.