Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::vector (ab)uses automatic storage

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?

like image 310
Igor R. Avatar asked Jan 06 '20 20:01

Igor R.


People also ask

How is C++ vector stored?

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.

How does std::vector allocate memory?

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.

How much memory does std::vector use?

So there is no surprise regarding std::vector. It uses 4 bytes to store each 4 byte elements. It is very efficient.

Is vector stored continuous?

Yes you can. The standard mandates that the memory in a std::vector is contiguous.


1 Answers

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.

like image 65
Yakk - Adam Nevraumont Avatar answered Sep 24 '22 23:09

Yakk - Adam Nevraumont