Search code examples
vectorrustbufferunsaferaw

How can I assign to an uninitialised vector without dropping the previous value?


I have a situation where I know how to initialise a vector, but I don't know the exact order of those elements.

let mut vector = todo!();
for (index, element) in &hash_map {
    vector[index] = element;
}

Now the problem is how to initialise the vector. The elements that it holds are not very lightweight, so I would prefer to cheat a little by creating an uninitialised vector:

let mut vector = Vec::with_capacity(size);
unsafe { vector.set_len(size) };

The problem is that when I later assign the value, I drop the previous element (which is uninitialised garbage) and panic:

vector[index] = element;

How can I assign an element to vector without triggering the default dropping behaviour?


Solution

  • You can use pointer::write or ptr::write:

    let mut vector: Vec<u8> = Vec::with_capacity(2);
    unsafe {
        let base = vector.as_mut_ptr();
        base.offset(0).write(42);
        vector.set_len(1);
    };
    println!("{:?}", vector);
    

    But it may be better to use MaybeUninit which is intended for this purpose.

    See also: