简体   繁体   中英

How do I reserve memory for a std::vector at construction time?

Normally I call reserve on a std::vector immediately after constructing it. Wouldn't this typically cause the std::vector 's existing heap allocation to be destroyed and replaced with a new one? Is there a way to reserve the memory at construction time rather than allocate heap space and then immediately destroy it? Or is there an implemenatation trick within the std::vector to ensure this is not an issue?

The available constructors only seem to be able to be useful for filling the std::vector with values, rather than reserving space explicitly.

Your question is based on a false premise, namely that a default-constructed std::vector<T> will perform a [zero-length] allocation.

There is literally no reason for it to do so. A fresh vector should have capacity zero (though this is required by sanity, not by the standard).

As such, your goal is already inherently satisfied.

To be blunt, the standard library is not quite that stupid.

If the number of elements is known at compile-time by you, you can list-initialize the vector with such elements:

 class MyClass 
 {
      int x, y, z;
      std::vector<int> v;

  public:
         MyClass(int X, int Y, int Z) : x(X), y(Y), z(Z), v{x, y, z}
         {}
 };

But this isn't very nice to maintain. There are more advanced techniques, such as custom allocators that you can make std::vector to use that could take memory from a pre-allocated memory pool, for instance: I doubt you really need that, however. Modern implementations would optimize a so simple problem easily.

The reason may be ironic, we are running out of function signature.

The requirement comes from the using scenario that we exactly know how many elements we will save into vector but we really really don't like the n-duplicated elements constructor:

std::vector( size_type count, const T& value = T())

Unfortunately the signature is occupied by the above constructor. Any other possible signature may cause issue. Eg

  1. vector(size_type count, size_type reserve_count) will conflicts with above n-duplicated elements constructor for vector of T(size_type) .

  2. vector(size_type count, const T& value = T(), size_type reserve_count) is a possible solution but it is too long and still boring. We need to construct a default value we never use while calling auto v = vector<T>(0, T(), reserve_count)

Other feasible solutions:

  1. Provides a function like make_pair/make_unique.

  2. Defines a Reserver which derived from Allocator, so we can use the constructor vector( const Allocator& alloc ) like

auto v = vector<Type>(new Reserver(reserve_count));

The object std::vector and its array of elements don't exist on the same contiguous memory block, otherwise its address would be changing every time you resize the array, making it impossible to keep a reliable reference of it. The object's main body only contains control variables and a pointer to the actual array, and it will be instanced in the stack (assuming you are using it as a local variable) along with the other local variables. And at this time the array will be empty, and probably represented by a pointer to nullptr . So it doesn't matter if you reserve at construct time or right after it, there will be no significant optimization happening.

If you want a std::vector with static size that is reserved instantly, you can just use a regular C array instead of std::vector . Just make sure it fits in the stack.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM