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

