default() method is implemented by a user and may panic midway through, leaving you with a half-initialized buffer. Because the items are considered owned, their destructors will be executed so we'll try to destroy garbage.
Something to keep in mind with
unsafe code is that it's not good enough to have UB only for a "short" time (i.e. having uninitialized data in something that is meant to be initialized, then initializing it in the next line). Once you trigger UB your program is broken and may cause the optimiser/code generator to make bad assumptions leading to unexpected behaviour.
You can't use assignment for initializing the array element. When you move an object into an array it'll call the destructor for the original. Instead, you should call
write() on a raw pointer (e.g.
I also prefer to use
array.as_ptr().offset(i) for retrieving a raw pointer to the i'th item instead of
&mut array[i] as *mut T. The
&mut array[i] bit means you're technically taking a mutable reference to uninitialized data, and references assume the data they point to is initialized. It still works and
miri probably won't complain, but feels a little wrong to me.
Have a look at the
alloc::raw_vec::RawVec from the standard library. It's the resizable buffer type that
Vec<T> builds on.
I'd also recommend reading the Example: Implementing Vec chapters from The Nomicon. They go through all the steps you'd take to implement your own
Vec<T>, including managing the memory, resizing, and implementing useful patterns (e.g.
I'm curious to hear how you got into this situation. As has already been mentioned, you aren't really saving any memory by coding your own
Vec<T>. Even ignoring that you are storing the size twice (
size field, and the size built into the slice's fat pointer).