0

I need to create a Vector of u8 whose memory address is sector size aligned. I saw another post which talks about same problem, but when I tried to implement it (playground link), it was not working.

use std::mem;

#[repr(C, align(64))]
struct AlignToSixtyFour([u8; 64]);

unsafe fn aligned_vec(n_bytes: usize) -> Vec<u8> {
    // Lazy math to ensure we always have enough.
    let n_units = (n_bytes / mem::size_of::<AlignToSixtyFour>()) + 1;

    let mut aligned: Vec<AlignToSixtyFour> = Vec::with_capacity(n_units);
    let ptr = aligned.as_mut_ptr();
    let len_units = aligned.len();
    let cap_units = aligned.capacity();

    mem::forget(aligned);

    let av = Vec::from_raw_parts(
        ptr as *mut u8,
        len_units * mem::size_of::<AlignToSixtyFour>(),
        cap_units * mem::size_of::<AlignToSixtyFour>(),
    );
    av
}

fn main() {
    println!("Hello, world!");
    unsafe {
        let mut kp = aligned_vec(1024);
        kp.resize(1024 as usize, 0);
        println!("align_of_val {:?}", mem::align_of_val(&kp));    // should be 64
        println!("align_of_val {:?}", mem::align_of_val(&kp[0])); // should be 64
    }
}

The output:

Hello, world!
align_of_val 8
align_of_val 1

Also the number to which vector should be aligned is variable, not known at compile time.

Rusting_It
  • 35
  • 5
  • Note that [`align_of_val`](https://doc.rust-lang.org/stable/std/mem/fn.align_of_val.html) would not be the right way to check whether the value's address fulfills a memory layout requirement. – E_net4 Sep 22 '22 at 10:20
  • As @E_net4thecommentflagger said, [it is aligned](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=7693bc6b94504f0ecdb0883d18b753fa). – Chayim Friedman Sep 22 '22 at 10:47
  • AFAICS the code as shown has two sources of Undefined Behaviour (`align_of_val(&aligned[0])` creates a reference to uninitialized memory; the `Vec` will be allocated with alignment of `64`, but deallocated with alignment of `1`). Maybe you could update your question to better reflect what you are _actually_ trying to do, that is, what you need the pointer for. – user2722968 Sep 22 '22 at 10:49
  • Yeah, I can use : `fn happens_to_be_aligned_to(ptr: *const T) -> usize {` `let addr = ptr as *const u8 as usize;` `1 << addr.trailing_zeros()` `}` I am just trying to create a vector of u8 which is aligned to 64. Also the size of vector is known at compile time but not the size of vector – Rusting_It Sep 22 '22 at 11:14
  • @user2722968 The UB is actually on the `from_raw_parts()` already. For two reasons: uninitialized and alignment. – Chayim Friedman Sep 22 '22 at 11:25
  • And also on the first `set_len()`. – Chayim Friedman Sep 22 '22 at 11:28
  • So, is there anyway to get aligned vector of u8 aligned to 512, If yes, please tell me how? – Rusting_It Sep 26 '22 at 05:49
  • This seems like a really weird thing to do, can you elaborate on why you need this alignment and how you intend to use it? – YthanZhang Sep 27 '22 at 09:24

0 Answers0