How come giving length =10 still works its memory out of slice ,length of slice16 should be half the size of slice

fn main() {
    let slice: &[u8] = &[1, 2, 3, 4, 5];
    let ptr = slice.as_ptr();
    let i = usize::from(ptr as usize & 1 != 0);

    let slice16: &[u16] = unsafe {
        std::slice::from_raw_parts(ptr.add(i).cast::<u16>(), 10)
    };

    dbg!(slice16);
}

You have UB. Run it under Miri (Tools->Miri in the playground).

4 Likes

Because you told it so and promised that it would be correct.

from_raw_parts takes what you give it as granted. That's why it is an unsafe function, which requires the developer to uphold the safety requirements of it. Which your code doesn't.
It's undefined behavior and Miri will tell you as much (as @chrefr mentioned)

5 Likes

Also note that alignment is a potential problem when you cast &[u8] to &[u16].

2 Likes

Thank you for letting me know about this tool, Miri. Yes, it's a UB, and now I am content with the result.

Yep, Thank you.

You are confusing "undefined behavior" with "guaranteed crash".

Undefined – trivially – means not defined. It does not mean crashing, producing any particular result (including "wrong" results you may expect), or any specific behavior. It means literally anything is allowed to happen, including your non-volatile storage being erased, or your hardware catching fire.

(And yes, these are completely realistic outcomes, eg. on embedded systems with MMIO, where MMIO controls real hardware. Not everything is "x64 Linux on a Lenovo laptop".)

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.