Why is Box::new_uninit_slice(len) safe?

⚓ Rust    📅 2025-05-02    👤 surdeus    👁️ 5      

surdeus

Warning

This post was published 111 days ago. The information described in this article may have changed.

Hi!

I am quite new with RUST and do some experiments to understand the borrow checker and memory management. I have written the following code:

use std::mem::MaybeUninit;

#[derive(Debug)]
struct Droppable {
    value: u32,
}

impl Drop for Droppable {
    fn drop(&mut self) {
        println!("dropping {}", self.value);
    }
}

fn main() {
    let len = 4;

    let mut b_values: Box<[MaybeUninit<Droppable>]> = Box::new_uninit_slice(len);
    b_values[0].write(Droppable { value: 0});
    b_values[1].write(Droppable { value: 1});
    unsafe { b_values.assume_init()};
    println!("done");
}

I know this is "bad code", as only the first two of four elements in the array are initialized. The output is (or similar):

dropping 0
dropping 1
dropping 7077989
dropping 3276851
done

Not surprising, as I never initialized member 2 and 3.

When I remove the line

    unsafe { b_values.assume_init()};

no element is dropped. Not surprising, as I never declare the memory as initialized, to make the borrow "responsible" for that memory.

But why I am allowed to write this code? In my expectation

Box::new_uninit_slice(len);

should be unsafe to forbid this kind of bug.

Regards

Roger

6 posts - 4 participants

Read full topic

🏷️ rust_feed