C++ vector STL 詳解

Reference:

C++ STL 之 vector 用法詳解
cplusplus docs
STL之vector容器詳解html

size VS capacity

  • size: number of elements in the vector.
  • capacity: the size of the storage space currently allocated for the vector, expressed in terms of elements.(分配的內存大小,用完時會自動relocate)

reserve

void reserve (size_type n);

 使vector的capacity至少能容納n個元素。若n比原始capacity值大,從新分配內存使vector的capacity爲n;若n小於等於原有capacity,啥也不作。resize改的是capacity。express

resize

void resize (size_type n);
void resize (size_type n, const value_type& val);
Resizes the container so that it contains n elements.

若原有size比n大,多出來的部分destroy掉;若size比n小,有指定val值時補val,不然補0。resize改的是size。segmentfault

std::vector<int> v;
for (int i=0; i<10; i++)
{
    v.push_back(i);
} // v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

v.resize(5); // v = {1, 2, 3, 4, 5}
v.resize(8,100); // v = {1, 2, 3, 4, 5, 100, 100, 100}
v.resize(12); // v = {1, 2, 3, 4, 5, 100, 100, 100, 0, 0, 0, 0}

erase

iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);
Removes from the vector either a single element (position) or a range of elements ([first,last)).
This effectively reduces the container size by the number of elements removed, which are destroyed.
Because vectors use an array as their underlying storage, erasing elements in positions other than the vector end causes the container to relocate all the elements after the segment erased to their new positions. This is generally an inefficient operation compared to the one performed for the same operation by other kinds of sequence containers (such as list or forward_list).
  1. Reduce size, while capacity remain the same. 改size不動capacity。
  2. Low efficiency. 效率低不推薦。
// erase
vector<int> b = {10, 20, 30, 40, 50};
cout << "\n##### test erase #####\n";
cout << "b size: " << b.size() << "\t b capacity: " << b.capacity() << endl; // 5 5
b.erase(b.begin());
cout << "After erase. b size: " << b.size() << "\t b capacity: " << b.capacity() << endl;// 4 5

erase 只能對size內的element進行操做,在capacity包含但size中不包含的位置是不能erase的,會引發內存錯誤。app

clear

void clear() noexcept;
Clear content
Removes all elements from the vector (which are destroyed), leaving the container with a size of 0.
A reallocation is not guaranteed to happen, and the vector capacity is not guaranteed to change due to calling this function. A typical alternative that forces a reallocation is to use swap:
vector<T>().swap(x);   // clear x reallocating

size降爲0,但capacity不必定會改變。爲保險起見,推薦使用swap函數

vector<int> a = {1, 2, 3};
// test clear
cout << "a size: " << a.size() << "\t a capacity: " << a.capacity() << endl; // 3 3
a.clear();
cout << "a size: " << a.size() << "\t a capacity: " << a.capacity() << endl; // 0 3

使用Swap()進行內存釋放

vector的成員函數clear並不會釋放內存,故能夠使用swap()函數進行內存釋放。this

vector<int> v(5, 10);
cout << "v size: " << v.size() << "\t v capacity: " << v.capacity() << endl; // 5 5
v.clear();
cout << "v size: " << v.size() << "\t v capacity: " << v.capacity() << endl; // 0 5
vector<int>().swap(v);
cout << "v size: " << v.size() << "\t v capacity: " << v.capacity() << endl; // 0 0

assign

Assigns new contents to the vector, replacing its current contents, and modifying its size accordingly.
vector<int> a = {1, 2, 3};
vector<int> b = {10, 20, 30, 40, 50};
// assign
// usage 1: void assign (InputIterator first, InputIterator last);
// c.assign(beg,end)將[beg,end)一個左閉右開區間的數據賦值給c。
cout << "b size: " << b.size() << "\t b capacity: " << b.capacity() << endl; // 5 5
b.assign(a.begin(), a.begin() + 2);
cout << "After assigin. b size: " << b.size() << "\t b capacity: " << b.capacity() << endl; // 2 5
cout << "print b: ";
for (auto element: b)
{
    cout << element << "\t";
} // 1 2
cout << endl;

// usage 2: void assign (size_type n, const value_type& val);
// c.assign (n, elem)將n個elem的拷貝賦值給c。
vector<int> v;
v.assign(5,10);// v = {5, 5, 5, 5, 5}

find

vector沒有查找元素存在性的成員函數,使用順序容器的通用方法algorithm中的find()函數spa

// InputIterator find (InputIterator first, InputIterator last, const T& val);
#include <algorithm>    // std::find
vector<int> v = { 1, 2, 3, 4 };
auto it_1 = find(v.begin(), v.end(), 1); // it_1 = v.begin();
autp it_2 = find(v.begin(), v.end(), 9); // it_2 = v.end();

壓縮臃腫的vector

不少時候大量的刪除數據致使vector的capacity遠大於實際使用的size,須要壓縮臃腫的vector,將vector壓縮到其實際的size大小。注意一個特性:code

std::vector<int> v(5, 10); // v = {10, 10, 10, 10, 10}
cout << "v size: " << v.size() << "\t v capacity: " << v.capacity() << endl; // 5 5
v.clear();
v.push_back(1); v = {1}
cout << "v size: " << v.size() << "\t v capacity: " << v.capacity() << endl; // 1 5
std::vector<int> v1(v);
cout << "v1 size: " << v1.size() << "\t v1 capacity: " << v1.capacity() << endl; // 1 1

用一個vector構建另外一個vector時會按其實際size構造而不是按capacity。所以咱們藉助這一特性加上swap()函數,來完成對vector的壓縮。orm

std::vector<int> v(5, 10);
cout << "v size: " << v.size() << "\t v capacity: " << v.capacity() << endl; // 5 5
v.clear();
v.push_back(1);
cout << "v size: " << v.size() << "\t v capacity: " << v.capacity() << endl; // 1 5
vector<int>(v).swap(v);
cout << "v size: " << v.size() << "\t v capacity: " << v.capacity() << endl; // 1 1

這樣便可將vector壓縮到其實際大小1在C++11中出現了shrink_to_fit()函數實現vector的壓縮。htm

std::vector<int> v(5, 10);
cout << "v size: " << v.size() << "\t v capacity: " << v.capacity() << endl; // 5 5
v.clear();
cout << "v size: " << v.size() << "\t v capacity: " << v.capacity() << endl; // 0 5
v.shrink_to_fit();
cout << "v size: " << v.size() << "\t v capacity: " << v.capacity() << endl; // 0 0
相關文章
相關標籤/搜索