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;
}
c/c++ 學習互助QQ群:877684253
本人微信:xiaoshitou5854