c/c++ 標準容器 vector的記憶體空間是如何自動增長的

小石王發表於2018-09-14

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

相關文章