0
点赞
收藏
分享

微信扫一扫

vector容器成员函数——reserve()及迭代器失效问题

青乌 2022-04-21 阅读 59
c++

文章目录

一、vector容器成员函数——reserve()

2.实用意义:

vecotr容器中不断的push_back(), 会进行多次内存再分配行为,为了减少内存再分配的次数,下面有请reserve()函数出场!!!

3.功能:

增加vector容器容量 c a p a c i t y capacity capacity

4.使用方法

函数原型:

void reserve( size_type new_cap );

参数介绍:

5.例子

  • 5.1 结论reserve()不改变vector的大小 s i z e size size,改变vector的容量 c a p a c i t y capacity capacity,以下是证明:
int foo()
{
    vector<int> v{ 1, 3, 5, 7, 9 };
    cout << v.size() << endl;		// 5
    cout << v.capacity() << endl;	// 5
    
    v.reserve(10);	// (1) 改变vector的什么呢?
    cout << "After reserve(): " << endl;	

    cout << v.size() << endl;		// 5,看!不改变vector的元素个数
    cout << v.capacity() << endl;	// 10,改变了vector的容量!

    return 0;
}
  • 5.2 结论reserve(new_cap),当new_cap大于vector原本的容量时,迭代器会失效!!

    当要分配的新容量大于vector原本的容量时,vector会找一个更大的空间,然后vector中的所有元素将会拷贝到这个更大的新空间里,这时所有迭代器将会失效。为什么会失效?

    以下是证明:

    void test5_2(vector<int>& v)
    {
        vector<int>::iterator iter = v.begin();
        for (;iter != v.end(); ++iter)
            cout << *iter << " ";	// 1, 3, 5, 7, 9
        cout << endl;
    
        v.reserve(10);
    
        for (;iter != v.end(); ++iter)
            cout << *iter << " ";	// 一堆随机数
        cout << endl;
        return ;
    }
    

    那如何处理迭代器失效呢?其实再给迭代器赋值一次v.begin()就好辣!

    void test5_2(vector<int>& v)
    {
        vector<int>::iterator iter = v.begin();
        for (;iter != v.end(); ++iter)
            cout << *iter << " ";
        cout << endl;
    
        v.reserve(10);
    	iter = v.begin();	// 就看这一行!!!,比上面代码就多了这一句
        for (;iter != v.end(); ++iter)
            cout << *iter << " ";	
        cout << endl;
        return ;
    }
    

    聪明的你一定早就知道方法啦,还是看一下输出吧:

    1 3 5 7 9
    1 3 5 7 9
    

    这下迭代器就没事啦!

    到这里一定很好奇,如果reserve(new_cap)中的new_cap小于vector原本的容量,那将会怎么样?

    测试结论是没有任何效果,所以还是安安分分使用reserve()作为vector扩容的方法吧,如果需要缩小vector容量,可以使用shrink_to_fit()。

    测试证明:

    void test5_1(vector<int>& v)
    {
        cout << v.size() << endl;		// 5
        cout << v.capacity() << endl;	// 5
    
        v.reserve(8);
        cout << "After reserve(8): " << endl;
    
        cout << v.size() << endl;		// 5
        cout << v.capacity() << endl;	// 8,不出预料变8了	
    	
        v.reserve(3);	// 我缩!!
        cout << v.size() << endl;   	// 5
        cout << v.capacity() << endl;	// 8,没有起任何效果
        return ;
    }
    

6.注意

  1. 正确使用reserve可以避免不必要的内存再分配,例如,未初始化的vector变量v1,如果多次进行push_back()操作,必然会有多次内存再分配的操作。如果在push_back()之前使用reserve进行一次合理的扩容,那就会提高性能。
  2. 当vector按引用传递给函数作参数时,如果不知道该vector的使用特征,还是不要使用reserve()为好。

最后,如果有误,烦请各位指出!!

举报

相关推荐

0 条评论