Search code examples
rustslicedynamic-memory-allocation

How do I allocate a slice in Rust with a slice known at runtime?


I have seen replies telling you to use Vec::with_capacity(some_size); but that feels weird.

Why do I need to use a Vector to get a slice? I do not want to grow the slice later, I just want to use a plain slice, but the size is known at runtime because it comes from some program input.

My current solution is:

   let mutable_zeroed_slice: &mut [u8] = &mut vec![0; size][..];

Is there a better, more idiomatic and non convoluted?

Updated: You can't use the trick before wrapped within a function as you will lose the slice reference upon return.

Update 2: As pointed out in the first reply, Vec::with_capacity(size)[..] will give you an immutable empty slice with the given capacity, which is not very useful.


Solution

  • You don't want the growable property, but you still need the storage to be allocated.

    &[u8] refers to some data allocated somewhere; the Vec you try to create here will disappear at the end of the function, then any slice referring to its content will be dangling, and Rust prevents you from doing that.

    The idea is to use a boxed-slice: it is boxed in order to allocate the storage, but it is not growable (as vectors are). An easy way to achieve this is to build a vector, then steal its content.

    Note that you seem to make a confusion between capacity and size/length.

    fn new_byte_slice(size: usize) -> Box<[u8]> {
        vec![0; size].into_boxed_slice()
    }
    
    fn main() {
        let values = new_byte_slice(10);
        println!("{:?}", values);
    }
    /*
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    */