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?
Vectors in C++ are sequence containers representing arrays that can change their size during runtime. They use contiguous storage locations for their elements just as efficiently as in arrays, which means that their elements can also be accessed using offsets on regular pointers to its elements.
As mentioned above, std::vector is a templated class that represents dynamic arrays. std::vector typically allocates memory on the heap (unless you override this behavior with your own allocator). The std::vector class abstracts memory management, as it grows and shrinks automatically if elements are added or removed.
So there is no surprise regarding std::vector. It uses 4 bytes to store each 4 byte elements. It is very efficient.
Yes you can. The standard mandates that the memory in a std::vector is contiguous.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With