Search code examples
c++memorystldynamic-memory-allocation

How to avoid reallocation using the STL (C++)


This question is derived from the topic:

vector reserve c++

I am using a datastructure of the type vector<vector<vector<double> > >. It is not possible to know the size of each of these vector (except the outer one) before items (doubles) are added. I can get an approximate size (upper bound) on the number of items in each "dimension".

A solution with the shared pointers might be the way to go, but I would like to try a solution where the vector<vector<vector<double> > > simply has .reserve()ed enough space (or in some other way has allocated enough memory).

Will A.reserve(500) (assumming 500 is the size or, alternatively an upper bound on the size) be enough to hold "2D" vectors of large size, say [1000][10000]?

The reason for my question is mainly because I cannot see any way of reasonably estimating the size of the interior of A at the time of .reserve(500).

An example of my question:

vector<vector<vector<int> > > A;
A.reserve(500+1);
vector<vector<int> > temp2;
vector<int> temp1 (666,666);
for(int i=0;i<500;i++)
{
  A.push_back(temp2);
  for(int j=0; j< 10000;j++)
  {
    A.back().push_back(temp1);
  }
}

Will this ensure that no reallocation is done for A?

If temp2.reserve(100000) and temp1.reserve(1000) were added at creation will this ensure no reallocation at all will occur at all?

In the above please disregard the fact that memory could be wasted due to conservative .reserve() calls.

Thank you all in advance!


Solution

  • your example will cause a lot of copying and allocations.

    vector<vector<vector<double>>>  A;
     A.reserve(500+1);
     vector<vector<double>>  temp2; 
    vector<double> temp1 (666,666);
     for(int i=0;i<500;i++) 
    {
     A.push_back(temp2);
     for(int j=0; j< 10000;j++)
     {
     A.back().push_back(temp1);
     }
    } 
    

    Q: Will this ensure that no reallocation is done for A?
    A: Yes.

    Q: If temp2.reserve(100000) and temp1.reserve(1000) where added at creation will this ensure no reallocation at all will occur at all?
    A: Here temp1 already knows its own length on creation time and will not be modified, so adding the temp1.reserve(1000) will only force an unneeded reallocation.
    I don't know what the vector classes copy in their copy ctor, using A.back().reserve(10000) should work for this example.
    Update: Just tested with g++, the capacity of temp2 will not be copied. So temp2.reserve(10000) will not work.

    And please use the source formating when you post code, makes it more readable :-).