c/c++ 標準容器 vector的記憶體空間是如何自動增長的 vector,string,deque的記憶體存儲機制:在一個連續的記憶體空間存儲,所以才支持下標操作。 vector的課題:由於容器的大小是可變的,當插入元素後,vector必須分配新的記憶體來保存已有元素和新的元素,將已有元素從舊的記憶體地址 ...
c/c++ 標準容器 vector的記憶體空間是如何自動增長的
vector,string,deque的記憶體存儲機制:在一個連續的記憶體空間存儲,所以才支持下標操作。
vector的課題:由於容器的大小是可變的,當插入元素後,vector必須分配新的記憶體來保存已有元素和新的元素,將已有元素從舊的記憶體地址移動到新的記憶體地址,並釋放掉舊的記憶體空間。如果我們每添加一個新元素,vector就執行一次這樣的記憶體分配和釋放操作,性能會慢到不可接受
解決方案:為了避免這種代價,標準庫實現者採用了可以減少容器空間重新分配次數的策略。當不得不獲取新的記憶體空間時,vector和string的實現通常會分配比新的要求空間更大的記憶體空間。容器預留這些空間備用,可用來保存更多的元素。這樣,就不需要每次添加新元素都重新分配容器的記憶體空間了。
有了上述的背景,就有了下麵的函數:
capacity | 返回size + 預留空間的大小 |
---|---|
reserve(n) | 分配至少能容納n個元素的空間 |
shrink_to_fit | 將capacity()減少為為與size()相同大小 |
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <forward_list>
#include <deque>
using namespace std;
int main(){
//下麵代碼展示了size和capacity之間的相互作用
vector<int> ivec;
//size為0;capacity的值依賴於庫的具體實現
cout << " ivec:size: " << ivec.size()
<< " capaciy: " << ivec.capacity() << endl;
//想ivec添加24個元素
for(vector<int>::size_type i = 0; i != 24; ++i){
ivec.push_back(i);
}
//size為24;capacity大於等於24
cout << " ivec:size: " << ivec.size()
<< " capaciy: " << ivec.capacity() << endl;
//用reserve預分配一些額外的空間
ivec.reserve(50);
//size還是24;capacity大於等於50
cout << " ivec:size: " << ivec.size()
<< " capaciy: " << ivec.capacity() << endl;
//添加元素,用光多餘容量
while(ivec.size() != ivec.capacity()){
ivec.push_back(0);
}
//size為50;capacity為50
cout << " ivec:size: " << ivec.size()
<< " capaciy: " << ivec.capacity() << endl;
//再添加一個元素,vector就不得不重新分配空間
ivec.push_back(51);
//size為51;capacity的值依賴於庫的具體實現
cout << " ivec:size: " << ivec.size()
<< " capaciy: " << ivec.capacity() << endl;
//要求歸還記憶體
//shrink_to_fit只是一個請求,標準庫並不保證退還記憶體
ivec.shrink_to_fit();
//size為51;capacity的值依賴於庫的具體實現
cout << " ivec:size: " << ivec.size()
<< " capaciy: " << ivec.capacity() << endl;
}