How to correctly copy to uninitialized byte array or vec (example code wanted)?

I have a context.output(buf: &mut [u8]) that internally uses the segment-by-segment buf[some_segment_limit].copy_from_slice(internal_buffer) to copy bytes from the internal buffer to buf. Now I want to create a byte array or vec to receive the output bytes, the usual way is to create already initialized-by-zero memory with [0; N] or vec![0; len], which will result in a redundant write. So how can I use something like MaybeUninit to implement a direct copy to uninitialized memory? I can't seem to find code anywhere that does something similar for reference. The MaybeUninit example only shows an way to element-by-element initialization, not to initialize from the &mut [T] interface. (Or is the sound implementation difficult or impossible?)

Did you check that it actually does, and if so, that it matters (i.e., measurably too slow for your use case)? In particular, vec![0; len] can allocate pre-zeroed memory, see e.g. this example.

1 Like

the short answer is you don't.

if the interface expect buf: &mut [u8], you cannot use buf: &mut [MaybeUninit<u8>], the interface is not compatible. if you try to cast form &mut [MaybeUninit<u8>] to &mut [u8], it's instance UB if the slice is uninitialized, regardless whether the element is ever deferenced or not.

the only safe way (but may leak) to write to an MaybeUnint<T> is the MaybeUninit::write() method, if your API is not designed around MaybeUninit, there's a compatible (but unsafe) method through mut pointers, and that's pretty much it. the MaybeUninit usage is really limited in its current state. it's use case is mostly for out pointers in FFI calls.

there are various methods related to slices, but they are unstable now. but even if you enable the features using nightly toolchain, you still cannot use it with an interface expecting &mut [u8], you must re-design your API to take &mut [MaybeUninit<u8>] as argument. the relevant methods are write_slice(), write_slice_cloned(), and the slice_as_mut_ptr() (which itself is safe, but you need unsafe to write through a pointer, e.g. std::ptr::copy_non_overlapping()

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.