C++容器std::vector的swap()函數(shù)使用方式
std::vector中的常用函數(shù)
.clear();
清空數(shù)據(jù).size();
當(dāng)前vector容器內(nèi)存儲的元素的個數(shù).capacity();
當(dāng)前vector容器重新分配內(nèi)存之前所能容納的元素數(shù)量.swap();
函數(shù)交換.reserve();
向系統(tǒng)預(yù)訂一段足夠的連續(xù)的空間
.swap用于釋放內(nèi)存
首先,vector與deque不同,其內(nèi)存占用空間只會增長,不會減小。
比如你首先分配了10,000個字節(jié),然后erase掉后面9,999個,則雖然有效元素只有一個,但是內(nèi)存占用仍為10,000個。所有空間在vector析構(gòu)時回收。
在用vector時,輸入完一組數(shù)據(jù)處理完后,調(diào)用clear()進(jìn)行清理,如果此時打印vector[0],會發(fā)現(xiàn)仍然輸出之前vector所存的內(nèi)容,但是如果調(diào)用.empty()函數(shù)又會返回1,告訴我們這個容器現(xiàn)在是空的,什么原因?
這是因?yàn)槭褂?clear()清空內(nèi)容,但是沒有釋放內(nèi)存的原因。
舉例如下:
#include <iostream> #include <vector> using namespace std; int main() { vector <int >a; cout<<a.empty()<<endl;//輸出 1 代表該vector此時是空 a.push_back(1); a.push_back(2); cout<<a[0]<<" "<<a[1]<<endl;//輸出1 2 cout<<a.empty()<<endl;//輸出 0 代表該vector此時非空 cout<<a.size()<<endl;//輸出2 cout<<a.capacity()<<endl;//輸出2 cout<<"***************"<<endl; //a[0]=NULL;a[1]=NULL; 這是賦值為0,并不清空數(shù)據(jù),也不釋放內(nèi)存。 a.clear(); cout<<a[0]<<" "<<a[1]<<endl;//仍然輸出1 2,因?yàn)闆]有釋放內(nèi)存,所以輸出該地址的內(nèi)容仍然與之前一樣 cout<<a.empty()<<endl;//輸出1 代表該vector此時已經(jīng)為空 cout<<a.size()<<endl;//輸出0,代表當(dāng)前容器內(nèi)存儲元素個數(shù)是0,與.empty()類似,都告訴我們當(dāng)前容器是空的意思 cout<<a.capacity()<<endl;//輸出2,代表當(dāng)前該vector在重新分配存儲空間前所能容納的元素數(shù)量并沒有改變 cout<<"***************"<<endl; /* 下面這五行說明,.pop_back()與.clear()起到了相同的作用,都是清空數(shù)據(jù),但是沒有釋放內(nèi)存 while(!a.empty()){ a.pop_back(); } cout<<a.empty()<<endl;//輸出 1 代表該vector此時已經(jīng)為空 cout<<a[0]<<" "<<a[1]<<endl;//仍然輸出為 1 2,因?yàn)闆]有釋放內(nèi)存,所以輸出該地址的內(nèi)容仍然與之前一樣 */ a.push_back(4); cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<endl;//輸出 4 2 0 盡管沒有釋放內(nèi)存,但是已經(jīng)認(rèn)為該vector已經(jīng)被清空,所以再push_back();時,a[0]被覆蓋。 cout<<a.size()<<endl;//輸出1,代表當(dāng)前容器內(nèi)存儲元素個數(shù)是1,就是剛剛push_back();裝進(jìn)去的數(shù)起到的作用 cout<<a.capacity()<<endl;//此時仍然輸出2 cout<<"***************"<<endl;
在《effective STL》和其實(shí)很多C++文章中都有指明,用clear()無法保證內(nèi)存回收。但是swap技法可以。
那么如何釋放內(nèi)存呢?
我們用swap交換到一個新的類型的vector,將原來的a拷貝出去,然后自然銷毀,而新的到的a是全新的沒有存任何數(shù)據(jù)的。
具體方法如下所示:
vector<int>().swap(a); //或者如下所示 加一對大括號都可以,意思一樣的: { std::vector<int> tmp; ivec.swap(tmp); } //加一對大括號是可以讓tmp退出{}的時候自動析構(gòu) cout<<a.size()<<endl;//輸出 0 cout<<a.capacity()<<endl;.// 輸出 0 //cout<<a[1]<<endl;
.swap用于修剪掉多余空間
在一個應(yīng)用中,可能會需要向一個vector中插入很多記錄,比如說100000條,為了避免在插入過程中移動內(nèi)存,咱實(shí)現(xiàn)向系統(tǒng)預(yù)訂一段足夠的連續(xù)的空間,
例如:
vector<int> ivec; ivec.reserve(100000);
移動內(nèi)存問題是解決了。
但是如果后來這個vector不再需要存那么多的元素了,已經(jīng)通過erase刪除了。但是以前咱們預(yù)留的空間卻無法被其他程序再度利用,這樣會造成內(nèi)存一定程度上的浪費(fèi)。
于是,我們利用目前的vector構(gòu)造一個一模一樣的vector,他并沒有預(yù)留空間,于是以前預(yù)留的空間也被釋放以作他用了:
ivec.swap(vector<int>(ivec)); // or vector<int>(ivec).swap(ivec)
此時vector占用的多余空間將被釋放
或者如下所示 加一對大括號都可以,意思一樣的:
{ std::vector<int> tmp = ivec; ivec.swap(tmp); }
加一對大括號是可以讓tmp退出{}的時候自動析構(gòu);使用這種方法的前提是vector從前存儲了大量數(shù)據(jù),比如10000000,經(jīng)過各種處理后,現(xiàn)在只有100條,那么向清空原來數(shù)據(jù)所占有的空間,就可以通過這種交換技術(shù)swap技法就是通過交換函數(shù)swap(),使得vector離開其自身的作用域,從而強(qiáng)制釋放vector所占的內(nèi)存空間。
對于容器的去重復(fù)操作類似:
std::vector<int> ModuleArr; //排序 std::sort(ModuleArr.begin(), ModuleArr.end()); //去重 ModuleArr.erase(unique(ModuleArr.begin(), ModuleArr.end()), ModuleArr.end());
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
如何利用C語言位運(yùn)算解決只出現(xiàn)一次的數(shù)字
這篇文章主要給大家介紹了關(guān)于如何利用C語言位運(yùn)算解決只出現(xiàn)一次的數(shù)字的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04數(shù)據(jù)結(jié)構(gòu)之位圖(bitmap)詳解
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)之位圖詳解,本文講解了位圖的基本知識、位圖的實(shí)現(xiàn)方法、位圖的應(yīng)用等內(nèi)容,需要的朋友可以參考下2014-08-08在C++中實(shí)現(xiàn)高效的數(shù)組原地輪轉(zhuǎn)的方法總結(jié)
在 C++ 中,可以通過多種方式實(shí)現(xiàn)數(shù)組的輪轉(zhuǎn)操作,以下是幾種常見的實(shí)現(xiàn)方法及其對應(yīng)的代碼示例,文中通過代碼示例介紹的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下2025-04-04C++模擬實(shí)現(xiàn)vector示例代碼圖文講解
這篇文章主要介紹了C++容器Vector的模擬實(shí)現(xiàn),Vector是一個能夠存放任意類型的動態(tài)數(shù)組,有點(diǎn)類似數(shù)組,是一個連續(xù)地址空間,下文更多詳細(xì)內(nèi)容的介紹,需要的小伙伴可以參考一下2023-02-02C++11標(biāo)準(zhǔn)庫 互斥鎖 <mutex> 詳解
這篇文章主要介紹了C++11標(biāo)準(zhǔn)庫互斥鎖 <mutex> 的相關(guān)知識,使用call_once()的時候,需要一個once_flag作為call_once()的傳入?yún)?shù),本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2024-07-07深入探討POJ 2312 Battle City 優(yōu)先隊(duì)列+BFS
本篇文章是對優(yōu)先隊(duì)列+BFS進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05