Consider the following snippet:
#include <array>
int main() {
using huge_type = std::array<char, 20*1024*1024>;
huge_type t;
}
Obviously it would crash on most of platforms, because the default stack size is usually less than 20MB.
Now consider the following code:
#include <array>
#include <vector>
int main() {
using huge_type = std::array<char, 20*1024*1024>;
std::vector<huge_type> v(1);
}
Surprisingly it also crashes! The traceback (with one of the recent libstdc++ versions) leads to include/bits/stl_uninitialized.h
file, where we can see the following lines:
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
std::fill(__first, __last, _ValueType());
The resizing vector
constructor must default-initialize the elements, and this is how it's implemented. Obviously, _ValueType()
temporary crashes the stack.
The question is whether it's a conforming implementation. If yes, it actually means that the use of a vector of huge types is quite limited, isn't it?
There is no limit on how much automatic storage any std API uses.
They could all require 12 terabytes of stack space.
However, that API only requires Cpp17DefaultInsertable
, and your implementation creates an extra instance over what is required by the constructor. Unless it is gated behind detecting the object is trivially ctorable and copyable, that implementation looks illegal.