天天看點

C++11新特性(28)- 管理容器的容量

capacity和size

了解capacity和size的差別非常重要,容器的size是指已經儲存在容器中的資料的個數,而容量是指在不再重新配置設定記憶體的前提下容器最大可以包含的資料的個數。舉個例子:容量為2升的瓶子裝了1升水。2升是capacity,1升是size。

管理容器的容量

在絕大多數情況下,程式員不必關注容器類記憶體管理的細節,把這些工作完全交給C++标準庫。但是有時也會有例外:

  1. 要求操作的響應非常快,快到不能忽略從堆中申請記憶體的時間。
  2. 使用的空間非常大,大到不希望容器保持多餘的記憶體空間。

這時就需要主動幹預記憶體的取得和釋放動作。C++标準庫為此提供了相應的成員函數。

capacity:取得容器的容量

size:取得已經儲存在容器中資料的個數。

reserve:配置設定至少可以容納指定數量元素的記憶體空間。

shrink_to_fit:釋放多餘的記憶體空間,隻保留可以容納容器中資料的最小記憶體。

示例代碼

vector<int> v;
//v中沒有元素,capacity為0
cout << v.capacity() << endl;//0

v.reserve(1000);
//預先取得儲存1000個元素的空間,capacity為1000
cout << v.capacity() << endl;//1000

for(int i = 0; i < 1000; i++){
    v.push_back(i);
}
//空間已經取得,不再增加,capacity仍為1000
cout << v.capacity() << endl;//1000

for(int i = 0; i < 100000; i++){
    v.push_back(i);
}
//繼續添加元素,自動配置設定空間
cout << v.capacity() << endl;//128000

for(int i = 0; i < 100000; i++){
    v.pop_back();
}
//元素雖然删除,空間維持不變。
cout << v.capacity() << endl;//128000

v.shrink_to_fit();
//釋放多餘空間。
cout << v.capacity() << endl;//1000      

有兩點需要特别說明:

  1. 在添加元素時,為了減少記憶體配置設定的次數,記憶體空間會分段取得,是以經常會略大于資料的個數
  2. shrink_to_fit隻是發出釋放記憶體的請求,這個請求不一定總會被響應。

作者觀點

要求不是很嚴格的時候,可以充分享受語言帶來的便利和自由;條件很苛刻時,又可以實作充分的控制。這種收放自如的感覺恐怕隻有C++程式員才能享受。

繼續閱讀