Realloc Layout for Box<[MaybeUninit<T>]>?

I'd like to take a Box<[MaybeUninit<T>]>, take the raw pointer out of it, and reallocate it. However, my specific concern is that the realloc method specifies that:

  • layout is the same layout that was used to allocate that block of memory

If the Box was created via new_uninit_slice, is it safe to assume that Layout::array::<T>(box.len()) is the correct Layout builder to use for reallocating?

Why not use for_value? From the Box docs:

More precisely, a value: *mut T that has been allocated with the Global allocator with Layout::for_value(&*value) may be converted into a box using Box::<T>::from_raw(value). Conversely, the memory backing a value: *mut T obtained from Box::<T>::into_raw may be deallocated using the Global allocator with Layout::for_value(&*value).

1 Like

That seems simple enough. Just to clarify, what do I feed in to the for_value? Since this is a slice do I specify a length somewhere?

Just feed it a reference to the slice, it accepts references to non-Sized values.

fn example<T>(bx: Box<[MaybeUninit<T>]>) {
    let layout = Layout::for_value(&*bx);
}
2 Likes

(EDIT: Rewriting this as I made the classic realloc size mistake!)

That works, thank you! One follow-up question. For computing the new size, should I still use Layout::array()? If so, if I go to realloc this same box again, will for_value return the correct old layout (that was created via Layout::array this time)?

Realloc with a larger size? I believe array is the best option, yes. (It would be nicer if that was explicitly documented, but as far as I can see it's not.)

1 Like