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()函數只改變容器的元素數目,未改變容器大小。

 

(全文完)html

附:
一款簡易版STL的實現,項目地址: https://github.com/zinx2016/MiniSTL/tree/master/MiniSTL
相關文章
相關標籤/搜索