【探索】vector的内存管理与效率

版权声明:本文为博主原创文章,转载请注明出处-- https://blog.csdn.net/qq_38790716/article/details/85042557

1. 使用reverse()函数提前设定容量大小

1.1 提前设定的原因-

  • 对于vector和string,如果需要更多的内存空间,就会以类似realloc的思想来增长大小。vector容器支持随机访问,因此为了提高效率,它内部是使用动态数组的方式实现的

  • 在通过reverse()函数来申请特定大小的内存空间时总是按指数边界来增大其内部缓冲区;当执行insert或push_back等增加元素的操作时,如果此时动态数组的内存不够用,就要重新分配内存,再把原数组的内容复制过来,所以其访问速度与一般的数组相比,只有发生重新分配内存时,其性能才会下降

  • 因此如果需要对大量的数据进行push_back操作,应当使用reverse()函数提前设定其容量大小,否则会出现许多次内存分配,造成效率低下

1.2 提前设定的原因-|

之前我们在《C++ primer》以及《STL源码剖析》中也都提及过这一点,即迭代器失效的问题
在源码剖析中我们知道了迭代器失效的原因是由于内存重新配置导致失效的,而在primer中我们是通过使用iter = vec.insert(iter, c);这样的方法来避免错误,但我们始终没有提及如何避免迭代器失效?那么现在我们应该了解了,避免容器的内存重新分配就能避免迭代器失效

  • reverse成员函数允许开发者最小化必须进行的重新分配的次数,因而可以避免真分配的开销和迭代器、指针、引用失效
  • 例如,下面这段代码:
vector<int> v;
for (int i = 1; i <= 1000; ++i)  v.push_back(i);

在大多数STL实现中,这段代码在循环过程中将会导致2~10次的重新分配,然后我们把代码改用reverse:

vector<int> v;
v.reverse(1000);
for (int i = 1; i <= 1000; ++i)  v.push_back(i);

则在这循环中将不会发生重新分配

1.3 使用reverse的情况

  • 当知道有多少元素将最后出现在容器中时,就可以提前reverse适当数量的空间
  • 保留可能需要的最大的空间,然后再添加完全部数据后,再修整掉多余的容量

2. 修整vector过剩空间

  • 修整过剩空间只需一条语句:
vector<int>(ivec).swap(ivec);
  • 让我们来做个简单的测试:
//test.cpp
#include <iostream>
#include <vector>
using namespace std;

int main()
{
        vector<int> vec;
        vec.reserve(1000);
        vec.push_back(1);
        vec.push_back(2);
        cout << "size = " << vec.size() << "capacity = "
                << vec.capacity() << endl;
        vector<int>(vec).swap(vec);
        cout << "size = " << vec.size() << "capacity = "
                << vec.capacity() << endl;
        return 0;
}

运行结果:
在这里插入图片描述
vector(ivec)表示建立一个临时vector,是ivec的一份拷贝,但拷贝时vector的拷贝构造函数只分配拷贝的元素需要的内存,所以该临时vector没有多余的容量。然后进行交换,ivec持有了临时vector没有多余的容量部分,而临时vector则持有ivec过剩的容量,语句结尾处,该临时vector被释放

3. 用swap方法释放vector所占内存

内心os:感觉与上述方法类似,不过是将临时vector换为一个空的vector

//使用如下方法
vector<int>().swap(v);
v.swap(vector<int>());
{ std::vector<int> tmp = v;  v.swap(tmp);  }

测试:

扫描二维码关注公众号,回复: 4613691 查看本文章
#include <iostream>
#include <vector>
using namespace std;

int main()
{
        vector<int> vec;
        vec.reserve(1000);
        vec.push_back(1);
        vec.push_back(2);
        cout << "size = " << vec.size() << "capacity = "
                << vec.capacity() << endl;
        vector<int>().swap(vec);
        cout << "size = " << vec.size() << "capacity = "
                << vec.capacity() << endl;
        return 0;
}

测试结果:
在这里插入图片描述

---------------------------------get--------------------------------------------------
1.reverse的真正了解以及使用
2.关于迭代器失效的改良方法
3.修整容器过剩空间的方法

猜你喜欢

转载自blog.csdn.net/qq_38790716/article/details/85042557