The flex_array crate provides a #[no_std] flexible array similar to std::Vec, but with enhanced control over memory usage and error handling. By allowing you to customize the types used for length, capacity, and indexing operations, FlexArr an alternative to Rust’s std::Vec and you can use it in a lot places where you might otherwise use Vec.
I created FlexArr to address some of the limitations inherent in Rust’s standard Vec. Here are the key benefits:
-
Reduced Memory Overhead On a 64-bit system, a typical
std::Vecuses 24 bytes for its metadata. By choosing a smaller integer type (e.g.,u32) for length and capacity,FlexArrcan reduce this overhead to just 16 bytes, making it especially useful for to help reduce memory bloat or in embedded systems with limited RAM. -
Fallible Allocations Unlike
std::Vec, which may panic on allocation failure,FlexArremploys fallible allocations. Instead of crashing your application, it returns aFlexArrErr, allowing you to implement more graceful error handling. This is particularly advantageous in environments where stability is critical. -
Custom Allocator Support Rust’s standard allocator API remains unstable. To work around this,
FlexArrintroduces theAltAllocatortrait as an alternative to the standardAllocatortrait. WithFlexArr, you can easily integrate custom memory allocators, and if the allocator API stabilizes in the future,AltAllocatorcan effectively become an alias forAllocator.
-
Customizable Metadata Types Tailor the size of your dynamic array’s metadata by choosing a custom
LengthType. This allows you to balance memory usage and performance based on your application's needs. -
no_stdCompatibility Designed to work in environments where the Rust standard library is not available, making it ideal for embedded systems and other constrained platforms.
-
std_allocEnables a wrapper type calledGlobalthat implementsAltAllocatorusing the standard allocator APIs. This provides a drop-in replacement for applications that rely on the standard memory allocator. -
alloc_unstableEnables support for Rust’s unstableAllocatortrait for custom memory allocators. When used in conjunction withstd_alloc, this feature re-exports theGlobaltype directly from thestdcrate rather than using the customGlobalwrapper provided byflex_array. -
alloc_api2Enables support for theallocator-api2crate, which also provides anAllocatortrait in stable rust. This way if you already have allocators written against this you can use them with theflex_arraycrate. Note: This feature should not be enabled withalloc_unstablefeature. If you want to use both just able to enablealloc_unstableandnightlyin theallocator-api2crate. Additionally, if you are using thenightlyfeature of theallocator-api2crate you will need to enable thealloc_unstablefeature.
Add flex_array to your Cargo.toml.
[dependencies]
flex_array = "0.2.5"If you want to enable the std allocator enable the std_alloc feature.
flex_array = { version = "0.2.5", features = ["std_alloc"] }use flex_array::FlexArr;
use flex_array::alloc::{AllocError, AltAllocator};
struct YourAllocator;
unsafe impl AltAllocator for YourAllocator {
fn allocate(
&self,
_layout: core::alloc::Layout,
) -> Result<core::ptr::NonNull<[u8]>, AllocError> {
todo!("Implement your custom allocator here");
}
unsafe fn deallocate(&self, _ptr: core::ptr::NonNull<u8>, _layout: core::alloc::Layout) {
todo!("Implement your custom allocator here");
}
}
fn main() {
// FlexArr with u32 length/capacity and if using the std allocator.
let mut array: FlexArr<i32> = FlexArr::new();
// Or
// Create an empty FlexArr with a custom allocator and a u16 for length/capacity.
let mut array: FlexArr<i32, YourAllocator, u16> = FlexArr::new_in(YourAllocator);
// Reserve capacity for 100 elements.
array.reserve(100).expect("Failed to allocate memory");
// Push elements into the array.
array.push(42).expect("Failed to push element");
// Access elements safely.
if let Some(value) = array.get(0) {
println!("First element: {}", value);
}
}I welcome any feedback and contributions! If you have suggestions for improvements, encounter any bugs, or discover potential soundness issues, please open an issue or submit a pull request. Although I've run tests and used Miri to check for issues. The unsafe code required to get a Vec like container while supporting multiple allocators means if you find any soundness issues please let me know so it can be dealt with promptly. Any input is kindly appreciated to ensure the quality and reliability of this crate.
- MIT license (LICENSE-MIT)