For example, this segfaults:
SmallVec4::<Box<u32>>::new();
SmallVec4<T> contains a [T; 4] field directly, which is initialized in new with std::mem::zeroed(). When the vector is dropped, the destructor for T is run for each of the 4 Ts, even if there isn’t actually a T there (i.e. if the vector’s length is less than 4 by the time it is dropped).
https://github.com/bluss/arrayvec works around this issue by having (simplified):
enum Array<T> {
Alive([T, 4]),
Dropped,
}
with a destructor that resets to Dropped before the recursive destructors are run implicitly.
In SmallVecN, the second variant could instead contain the pointer and capacity for a spilled vector (reset to null/zero during destruction).
For example, this segfaults:
SmallVec4<T>contains a[T; 4]field directly, which is initialized innewwithstd::mem::zeroed(). When the vector is dropped, the destructor forTis run for each of the 4Ts, even if there isn’t actually aTthere (i.e. if the vector’s length is less than 4 by the time it is dropped).https://github.com/bluss/arrayvec works around this issue by having (simplified):
with a destructor that resets to
Droppedbefore the recursive destructors are run implicitly.In
SmallVecN, the second variant could instead contain the pointer and capacity for a spilled vector (reset to null/zero during destruction).