zoukankan      html  css  js  c++  java
  • STL—vector空间的动态增长

    vector空间的动态增长

        当添加元素时,如果vector空间大小不足,则会以原大小的两倍另外配置一块较大的新空间,然后将原空间内容拷贝过来,在新空间的内容末尾添加元素,并释放原空间。vector的空间动态增加大小,并不是在原空间之后的相邻地址增加新空间,因为vector的空间是线性连续分配的,不能保证原空间之后有可供配置的空间。因此,对vector的任何操作,一旦引起空间的重新配置,指向原vector的所有迭代器就会失效。
     

    vector的size(),capacity(),reserve(),resize()函数

        vector对象的内存布局如下图所示。
         start迭代器指向已用空间的首元素,finish指向已用空间的尾元素的下一个位置,end_of_storage指向可用空间的末尾。
         size()函数返回的是已用空间大小,capacity()返回的是总空间大小,capacity()-size()则是剩余的可用空间大小。当size()和capacity()相等,说明vector目前的空间已被用完,如果再添加新元素,则会引起vector空间的动态增长。
         由于动态增长会引起重新分配内存空间、拷贝原空间、释放原空间,这些过程会降低程序效率。因此,可以使用reserve(n)预先分配一块较大的指定大小的内存空间,这样当指定大小的内存空间未使用完时,是不会重新分配内存空间的,这样便提升了效率。只有当n>capacity()时,调用reserve(n)才会改变vector容量。
        resize()成员函数只改变元素的数目,不改变vector的容量。
     
    程序说明:
        分配了两个容器a,b。其中每次往a中添加1个元素,共添加10次。使用reserve()预先为b分配一块10个元素大小的空间,之后才每次往b中添加1个元素,共添加10次。当b空间满后,再往其中添加1个元素。之后使用reserve()为b分配一块15(比原空间小)个元素大小的空间。再使用resize()将b的元素个数改变为5个。
        观察上述过程中size()和capacity()大小的变化。
    #include <iostream>
    #include <vector>
    using namespace std;
    int main()
    {
        vector<int> a;
        cout << "a.size(): " << a.size() << "       a.capacity(): " << a.capacity() << endl;
        for (int i = 0; i < 10; i++)
        {
            a.push_back(i);
            cout << "a.size(): " << a.size() << "   a.capacity(): " << a.capacity() << endl;
        }
        cout << endl;
        vector<int> b;
        b.reserve(10);
        for (int i = 0; i < 10; i++)
        {
            b.push_back(i);
            cout << "b.size(): " << b.size() << "   b.capacity(): " << b.capacity() << endl;
        }
        b.push_back(11);
        cout << "b.size(): " << b.size() << "       b.capacity(): " << b.capacity() << endl;
        cout << endl;
        b.reserve(15);
        cout << "after b.reserve(15):" << endl;
        cout << "b.size(): " << b.size() << "       b.capacity(): " << b.capacity() << endl;
        b.resize(5);
        cout << "after b.resize(5):" << endl;
        cout << "b.size(): " << b.size() << "       b.capacity(): " << b.capacity() << endl;
        return 0;
    }
    输出:
    a.size(): 0     a.capacity(): 0
    a.size(): 1     a.capacity(): 1
    a.size(): 2     a.capacity(): 2
    a.size(): 3     a.capacity(): 4
    a.size(): 4     a.capacity(): 4
    a.size(): 5     a.capacity(): 8
    a.size(): 6     a.capacity(): 8
    a.size(): 7     a.capacity(): 8
    a.size(): 8     a.capacity(): 8
    a.size(): 9     a.capacity(): 16
    a.size(): 10    a.capacity(): 16
    b.size(): 1     b.capacity(): 10
    b.size(): 2     b.capacity(): 10
    b.size(): 3     b.capacity(): 10
    b.size(): 4     b.capacity(): 10
    b.size(): 5     b.capacity(): 10
    b.size(): 6     b.capacity(): 10
    b.size(): 7     b.capacity(): 10
    b.size(): 8     b.capacity(): 10
    b.size(): 9     b.capacity(): 10
    b.size(): 10    b.capacity(): 10
    b.size(): 11    b.capacity(): 20
    after b.reserve(15):
    b.size(): 11    b.capacity(): 20
    after b.resize(5):
    b.size(): 5     b.capacity(): 20
    现象:a重新分配空间共5次,每次都为之前空间的2倍。b在未超出reserve()预分配的空间时没有重新分配。
    结论:
        1. 空的vector对象,size()和capacity()都为0
        2. 当空间大小不足时,新分配的空间大小为原空间大小的2倍。
        3. 使用reserve()预先分配一块内存后,在空间未满的情况下,不会引起重新分配,从而提升了效率。
        4. 当reserve()分配的空间比原空间小时,是不会引起重新分配的。
        5. resize()函数只改变容器的元素数目,未改变容器大小。

    (全文完)

    附:
    一款简易版STL的实现,项目地址:https://github.com/zinx2016/MiniSTL/tree/master/MiniSTL
     
     
     
  • 相关阅读:
    训练总结
    图论--最短路--SPFA模板(能过题,真没错的模板)
    图论--最短路-- Dijkstra模板(目前见到的最好用的)
    The 2019 Asia Nanchang First Round Online Programming Contest B Fire-Fighting Hero(阅读理解)
    关于RMQ问题的四种解法
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 K题 center
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 XKC's basketball team
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 D Carneginon
    ZOJ 3607 Lazier Salesgirl (枚举)
    ZOJ 3605 Find the Marble(dp)
  • 原文地址:https://www.cnblogs.com/zxiner/p/7197327.html
Copyright © 2011-2022 走看看