简体   繁体   中英

C++ memory allocation upon resizing of reserved std::vector

I am curious about the std::vector behavior and I could not find answer anywhere, so ...

Lets have an odd program:

std::vector<int> vec;
vec.reserve(5);
for(int i = 0; i < vec.size(); ++i) // OK, I have noticed the mistake in the condition, I am leaving it here for educational purposes
{
    vec.resize(vec.size() + 1);
    vec[i] = 42;
}

What the behavior in terms of memory allocations will be? Only one allocation upon memory reserving as expected, or resizing clears the memory it does not need?

For starters this loop will be executed never

std::vector<int> vec;
vec.reserve(5);
for(int i = 0; i < vec.size(); ++i)
{
    vec.resize(vec.size() + 1);
    vec[i] = 42;
}

because initially the size of the vector is equal to 0.

Maybe you mean something like the following

std::vector<int> vec;
vec.reserve(5);
for(int i = 0; i < vec.capacity(); ++i)
{
    vec.resize(vec.size() + 1);
    vec[i] = 42;
}

In this case the vector will not be reallocated.:)

Here is a demonstrative program

#include <iostream>
#include <vector>

int main()
{
    const size_t N = 5;

    std::vector<int> v;
    v.reserve( N );

    std::vector<int>::size_type i = 0;

    do
    {
        v.resize( v.size() + 1);
        std::cout << v.capacity() << '\t' << v.data() << std::endl;
    } while ( ++i < v.capacity() );

    return 0;
}

Its output might look like

5   0x824da10
5   0x824da10
5   0x824da10
5   0x824da10
5   0x824da10

What the reserve method actually does is:

Requests that the vector capacity be at least enough to contain n elements.

  • If n is greater than the current vector capacity , the function causes the container to reallocate its storage increasing its capacity to n (or greater).

  • In all other cases, the function call does not cause a reallocation and the vector capacity is not affected.

  • This function has no effect on the vector size and cannot alter its elements.

So, at first, vec.reserve(5); will allocate memory for 5 elements. (But the vector size will still be 0 )

Then, inside loop, you are calling vec.resize(vec.size() + 1); , let's first have a look, what does this function do:

What resize actually do is:

Resizes the container so that it contains n elements.

  • If n is smaller than the current container size , the content is reduced to its first n elements, removing those beyond (and destroying them).

  • If n is greater than the current container size , the content is expanded by inserting at the end as many elements as needed to reach a size of n . If val is specified, the new elements are initialized as copies of val , otherwise, they are value-initialized.

  • If n is also greater than the current container capacity , an automatic reallocation of the allocated storage space takes place.

  • Notice that this function changes the actual content of the container by inserting or erasing elements from it.

In your case, the program, in loop is always passing the n which is lower than the capacity of vec , so, no memory allocations will be performed, and only the size attribute will be changed.

reserve allocates space to hold the requested number of items. resize tells the vector how many items are currently in the container.

So if you reserve less then you specify with resize an allocation will occur. If you reserve more than you resize to, the subsequent resize doesn't require additional allocations.

vec.size() is 0 to begin with. vec.reserve(5) will allocate space for at least 5 elements. Your loop will then do nothing.

But let's assume that you meant to loop to 5 instead. Only the reserve call will allocate more memory to the vector. The resizes inside the loop, since they are less than or equal to the capacity of the vector, will only construct new elements in the already allocated space.

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