简体   繁体   English

调整保留的std :: vector大小时的C ++内存分配

[英]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 ... 我对std :: vector行为感到好奇,并且在任何地方都找不到答案,所以...

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. 因为最初向量的大小等于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: reserve方法的实际作用是:

Requests that the vector capacity be at least enough to contain n elements. 请求向量容量至少足以包含n元素。

  • 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). 如果n大于当前向量容量 ,则该函数使容器重新分配其存储,将其容量增加到n (或更大)。

  • 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); 因此,首先是vec.reserve(5); will allocate memory for 5 elements. 将为5元素分配内存。 (But the vector size will still be 0 ) (但向量大小仍为0

Then, inside loop, you are calling vec.resize(vec.size() + 1); 然后,在内部循环中,您正在调用vec.resize(vec.size() + 1); , let's first have a look, what does this function do: ,我们先来看一下此函数的作用:

What resize actually do is: resize实际上是:

Resizes the container so that it contains n elements. 调整容器的大小,使其包含n个元素。

  • If n is smaller than the current container size , the content is reduced to its first n elements, removing those beyond (and destroying them). 如果n小于当前容器的大小 ,则将内容减少到其前n元素,并删除超出范围的元素(并销毁它们)。

  • 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 . 如果n大于当前容器的大小 ,则通过在末尾插入所需数量的元素来扩展内容,以达到n大小 If val is specified, the new elements are initialized as copies of val , otherwise, they are value-initialized. 如果指定了val ,则将新元素初始化为val副本,否则将对它们进行值初始化。

  • If n is also greater than the current container capacity , an automatic reallocation of the allocated storage space takes place. 如果n也大于当前容器容量 ,则会自动重新分配已分配的存储空间。

  • 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. 在您的情况下,循环中的程序始终传递的n小于veccapacity ,因此,将不执行任何内存分配,仅更改size属性。

reserve allocates space to hold the requested number of items. reserve分配空间来容纳请求的项目数。 resize tells the vector how many items are currently in the container. resize告诉向量容器中当前有多少个项目。

So if you reserve less then you specify with resize an allocation will occur. 因此,如果预留的空间较少,则可以通过resize指定分配。 If you reserve more than you resize to, the subsequent resize doesn't require additional allocations. 如果保留的空间超出了调整大小的范围,则后续调整大小不需要额外的分配。

vec.size() is 0 to begin with. vec.size()是0。 vec.reserve(5) will allocate space for at least 5 elements. vec.reserve(5)将为至少5个元素分配空间。 Your loop will then do nothing. 您的循环将什么也不做。

But let's assume that you meant to loop to 5 instead. 但让我们假设您打算循环到5。 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. 由于循环内的调整大小小于或等于向量的容量,因此将仅在已分配的空间中构造新元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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