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
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM