How can I allocate aligned memory in Rust?

For FFI, I'd like to allocate aligned memory with a size that's defined at runtime. It'd be great if it's a vector, but it doesn't look like it's possible. Is there a cross-platform way to allocate aligned memory?

To be clear, this is what I'm looking for, approximately:

let size = get_object_size();
let alignment = size; // can only be 1-8 bytes
let v: Vec<u8> = Vec::new();
v.allocate_aligned(size, alignment);
assert_eq!(v.as_ptr() as i64 & (alignment - 1), 0);
assert_eq!(v.len(), size);

By default, Vec<T> guarantees that memory is properly aligned for type T. If you want to, say, allocate an over-aligned slice of bytes, you may find the "alloc" module of std interesting.

Once you have gotten you allocations the way you want, you can use std::slice::from_raw_parts[_mut] to wrap them behind a nicer Rust slice interface, but be sure to check that function's documentation as it has some important preconditions.

One (not so) obvious bit which the slice::from_raw_parts documentation does not mention is that you must initialize your data before building a Rust slice pointing to it.

Vec::from_raw_parts is possible as well, but probably too dangerous, because any reallocation would destroy all your hard work!


It would also cause undefined behavior as memory must be deallocated with the same alignment it was allocated with.


Nice catch, thanks!

1 Like

Sounds like you're looking for std::alloc::alloc(). It's given a Layout (size + alignment) and will return a raw pointer to some allocated memory using the global allocator.

This is all unsafe of course, but if you're doing FFI then I don't see it being a problem.

There's also Alloc::alloc_array(), but that requires a handle to an existing allocator, and the allocator API isn't stable yet.

1 Like

Quick-and-dirty hack

In the case where the alignment is one of 1, 2, 4, 8, picking 8 since the beginning removes the "runtime" dependency and allows to just allocate at least size bytes in memory by creating a Vec::<u64>::with_capacity(size / 8 + 1).

The proper way:

use ::core::ptr;
use ::std::alloc; // or extern crate alloc; use ::alloc::alloc;

fn alloc (numbytes: usize, alignment: usize)
  -> Option<ptr::NonNull<()>>
    if numbytes == 0 { return None; }
    let layout =
        alloc::Layout::from_size_align(numbytes, alignment)
            .map_err(|err| eprintln!("Layout error: {}", err))
    ptr::NonNull::new(unsafe {
        // # Safety
        //   - numbytes != 0

/// # Safety
///   - `ptr`, when `NonNull`, must be a value returned by `alloc(numbytes, alignment)`
#[require_unsafe_in_body] // or #[allow(unused_unsafe)]
fn free (
    ptr: Option<ptr::NonNull:<()>>,
    numbytes: usize,
    alignment: usize,
    let ptr = if let Some(ptr) = ptr { ptr } else { return; };
    let layout =
        alloc::Layout::from_size_align(numbytes, alignment)
            .unwrap_or_else(|err| {
                // if same layout as input this should not happen,
                // so it is a very bad bug if this is reached
                eprintln!("Layout error: {}", err);
    unsafe {
        // # Safety
        //   - `ptr` came from alloc::alloc(layout);
        alloc::dealloc(ptr.cast::<u8>().as_ptr(), layout);
  • Where I have used #[require_unsafe_in_body] to remove Rust mistakenly not requiring unsafe blocks in unsafe fn function bodies.