1. 程式人生 > >STL學習筆記之使用reserve來避免不必要的重新分配

STL學習筆記之使用reserve來避免不必要的重新分配

關於STL容器,只要你不超過它們的最大大小,它們就可以自動增長以滿足你的要求。對於vector和string,只要需要更多的空間,就可以用realloc等價思想來增長。這個操作有四個部分。

1.     分配新的記憶體塊,在大部分實現中,vector和string的容量每次以2為因數增長。

2.     把所有元素從容器的就記憶體拷貝到它新的記憶體。

3.     銷燬就記憶體中的物件。

4.     回收就記憶體。

給了所有的分配,回收,拷貝和析構,你就應該知道那些步驟都很昂貴。reserve成員函式允許你最小化必須進行的重新分配的次數,因而可以避免真分配的開銷和迭代器/指標/引用失效。

reserve(Container::size_type n)強制容器把它的容量改為至少n,提供的n不小於當前大小。

例如,假定你想建立一個容納1-1000值的vector<int>。沒有使用reserve,你可以像這樣來做:

vector<int> v;

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

在大多數STL實現中,這段程式碼在迴圈過程中將會導致2到10次重新分配。

把程式碼改為使用reserve,我們得到這個:

vector<int> v;

v.reserve(1000);

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

這在迴圈中不會發生重新分配。

在大小和容量之間的關係讓我們可以預言什麼時候插入將引起vector或string執行重新分配,而且,可以預言什麼時候插入會使指向容器中的迭代器、指標和引用失效。例如,給出這段程式碼,

string s;

...

if (s.size() < s.capacity()) {

              s.push_back('x');

}

push_back的呼叫不會使指向這個string中的迭代器、指標或引用失效,因為string的容量保證大於它的大小。如果不是執行push_back,程式碼在string的任意位置進行一個insert,我們仍然可以保證在插入期間沒有發生重新分配,但是,與伴隨string插入時迭代器失效的一般規則一致,所有從插入位置到string結尾的迭代器/指標/引用將失效。

通常有兩情況使用reserve來避免不必要的重新分配。第一個可用的情況是當你確切或者大約知道有多少元素將最後出現在容器中。那樣的話,就像上面的vector程式碼,你只是提前reserve適當數量的空間。第二種情況是保留你可能需要的最大的空間,然後,一旦你新增完全部資料,修整掉任何多餘的容量。

轉:http://archercai.blog.sohu.com/54816336.html