詳解C++ STL vector容量(capacity)和大小(size)的區(qū)別
很多初學(xué)者分不清楚 vector 容器的容量(capacity)和大小(size)之間的區(qū)別,甚至有人認(rèn)為它們表達(dá)的是一個意思。本節(jié)將對 vector 容量和大小各自的含義做一個詳細(xì)的介紹。
vector 容器的容量(用 capacity 表示),指的是在不分配更多內(nèi)存的情況下,容器可以保存的最多元素個數(shù);而 vector 容器的大?。ㄓ?size 表示),指的是它實(shí)際所包含的元素個數(shù)。
對于一個 vector 對象來說,通過該模板類提供的 capacity() 成員函數(shù),可以獲得當(dāng)前容器的容量;通過 size() 成員函數(shù),可以獲得容器當(dāng)前的大小。例如:
#include <iostream> #include <vector> using namespace std; int main() { std::vector<int>value{ 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47 }; value.reserve(20); cout << "value 容量是:" << value.capacity() << endl; cout << "value 大小是:" << value.size() << endl; return 0; }
程序輸出結(jié)果為:
value 容量是:20
value 大小是:15
結(jié)合該程序的輸出結(jié)果,圖 1 可以更好的說明 vector 容器容量和大小之間的關(guān)系。
圖 1 vector 容量和大小的區(qū)別
顯然,vector 容器的大小不能超出它的容量,在大小等于容量的基礎(chǔ)上,只要增加一個元素,就必須分配更多的內(nèi)存。注意,這里的“更多”并不是 1 個。換句話說,當(dāng) vector 容器的大小和容量相等時,如果再向其添加(或者插入)一個元素,vector 往往會申請多個存儲空間,而不僅僅只申請 1 個。
一旦 vector 容器的內(nèi)存被重新分配,則和 vector 容器中元素相關(guān)的所有引用、指針以及迭代器,都可能會失效,最穩(wěn)妥的方法就是重新生成。
舉個例子:
#include <iostream> #include <vector> using namespace std; int main() { vector<int>value{ 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47 }; cout << "value 容量是:" << value.capacity() << endl; cout << "value 大小是:" << value.size() << endl; printf("value首地址:%p\n", value.data()); value.push_back(53); cout << "value 容量是(2):" << value.capacity() << endl; cout << "value 大小是(2):" << value.size() << endl; printf("value首地址: %p", value.data()); return 0; }
運(yùn)行結(jié)果為:
value 容量是:15
value 大小是:15
value首地址:01254D40
value 容量是(2):22
value 大小是(2):16
value首地址: 01254E80
可以看到,向“已滿”的 vector 容器再添加一個元素,整個 value 容器的存儲位置發(fā)生了改變,同時 vector 會一次性申請多個存儲空間(具體多少,取決于底層算法的實(shí)現(xiàn))。這樣做的好處是,可以很大程度上減少 vector 申請空間的次數(shù),當(dāng)后續(xù)再添加元素時,就可以節(jié)省申請空間耗費(fèi)的時間。
因此,對于 vector 容器而言,當(dāng)增加新的元素時,有可能很快完成(即直接存在預(yù)留空間中);也有可能會慢一些(擴(kuò)容之后再放新元素)。
修改vector容器的容量和大小
另外,通過前面的學(xué)習(xí)我們知道,可以調(diào)用 reserve() 成員函數(shù)來增加容器的容量(但并不會改變存儲元素的個數(shù));而通過調(diào)用成員函數(shù) resize() 可以改變?nèi)萜鞯拇笮。⑶以摵瘮?shù)也可能會導(dǎo)致 vector 容器容量的增加。比如說:
#include <iostream> #include <vector> using namespace std; int main() { vector<int>value{ 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47 }; cout << "value 容量是:" << value.capacity() << endl; cout << "value 大小是:" << value.size() << endl; value.reserve(20); cout << "value 容量是(2):" << value.capacity() << endl; cout << "value 大小是(2):" << value.size() << endl; //將元素個數(shù)改變?yōu)?21 個,所以會增加 6 個默認(rèn)初始化的元素 value.resize(21); //將元素個數(shù)改變?yōu)?21 個,新增加的 6 個元素默認(rèn)值為 99。 //value.resize(21,99); //當(dāng)需要減小容器的大小時,會移除多余的元素。 //value.resize(20); cout << "value 容量是(3):" << value.capacity() << endl; cout << "value 大小是(3):" << value.size() << endl; return 0; }
運(yùn)行結(jié)果為:
value 容量是:15
value 大小是:15
value 容量是(2):20
value 大小是(2):15
value 容量是(3):30
value 大小是(3):21
程序中給出了關(guān)于 resize() 成員函數(shù)的 3 種不同的用法,有興趣的讀者可自行查看不同用法的運(yùn)行結(jié)果。
可以看到,僅通過 reserve() 成員函數(shù)增加 value 容器的容量,其大小并沒有改變;但通過 resize() 成員函數(shù)改變 value 容器的大小,它的容量可能會發(fā)生改變。另外需要注意的是,通過 resize() 成員函數(shù)減少容器的大?。ǘ嘤嗟脑貢苯颖粍h除),不會影響容器的容量。
vector容器容量和大小的數(shù)據(jù)類型
在實(shí)際場景中,我們可能需要將容器的容量和大小保存在變量中,要知道 vector<T> 對象的容量和大小類型都是 vector<T>::size_type 類型。因此,當(dāng)定義一個變量去保存這些值時,可以如下所示:
vector<int>::size_type cap = value.capacity(); vector<int>::size_type size = value.size();
size_type 類型是定義在由 vector 類模板生成的 vecotr 類中的,它表示的真實(shí)類型和操作系統(tǒng)有關(guān),在 32 位架構(gòu)下普遍表示的是 unsigned int 類型,而在 64 位架構(gòu)下普通表示 unsigned long 類型。
當(dāng)然,我們還可以使用 auto 關(guān)鍵字代替 vector<int>::size_type,比如:
auto cap = value.capacity(); auto size = value.size();
到此這篇關(guān)于詳解C++ STL vector容量(capacity)和大小(size)的區(qū)別的文章就介紹到這了,更多相關(guān)C++ STL vector容量和大小內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(76.最小窗口子串)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(76.最小窗口子串),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C++ Boost MultiIndex使用詳細(xì)介紹
Boost是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱2022-11-11Pipes實(shí)現(xiàn)LeetCode(195.第十行)
這篇文章主要介紹了Pipes實(shí)現(xiàn)LeetCode(195.第十行),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08VisualStudio2022配置opencv的實(shí)現(xiàn)
本文主要介紹了VisualStudio2022配置opencv的實(shí)現(xiàn),文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-06-06