STL容器swap操作介紹

2021-10-09 05:27:43 字數 4116 閱讀 9896

今天通過這篇部落格,以兩個非常規視角介紹stl容器swap操作。swap操作非常容易理解,因為字面意思不多不少的表達了函式所做的事,也即「交換」,關於swap做了什麼唯一值得關注的就是交換的是指標而非內容。那麼交換之後容器的狀態呢,是否可以通過交換達到其他什麼目的呢。

常見的連續記憶體容器,例如vector,string,儲存元素的數量和容量是兩個不同的概念,而且大多數時候容量都大於數量。這是改善效率的一種做法,避免頻繁分配釋放記憶體。

使用者可以通過clear()清空容器,但clear()不會釋放容量。使用者可以通過shrink_to_fit()釋放容量至盡可能小,具體有多小呢,不同的實現有不同的結果。

重點來了!使用者還可以通過神奇的swap操作達到相同的目的,而且更通用更可靠,不會因為不同的stl底層實現得到不同的結果。網傳一種神奇的vector().swap(test_vec)操作可以釋放test_vec占用的記憶體,雖然釋放記憶體並不靠譜兒(之前有一片部落格「如何主動釋放c++程式中stl容器不願自動釋放的記憶體」介紹過一種更靠譜兒的方式)但是確實可以清空test_vec,可以清空元素,清空容量。swap也能達到shrink_to_fit()的目的。如果不希望清空,僅僅希望讓容量盡可能小,也是有辦法的,下文程式中有介紹。

swap之後兩個容器的內容發生了交換,而且!兩個容器的迭代器、指標、引用也會發生交換,a.swap(b)之後,a的迭代器依然有效,但是代表的元素位於b中。

#ifndef _common_h_

#define _common_h_

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

#endif

//swap_op.cpp

#include

"common.h"

intmain

(void

)printf

("test_vec_shrink.size(): %lu\n"

, test_vec_shrink.

size()

);printf

("test_vec_shrink.capacity(): %lu\n"

, test_vec_shrink.

capacity()

);printf

("test_vec_swap.size(): %lu\n"

, test_vec_swap.

size()

);printf

("test_vec_swap.capacity(): %lu\n"

, test_vec_swap.

capacity()

);test_vec_shrink.

shrink_to_fit()

;printf

("after shrink_to_fit:\ntest_vec_shrink.size(): %lu\n"

, test_vec_shrink.

size()

);printf

("test_vec_shrink.capacity(): %lu\n"

, test_vec_shrink.

capacity()

);vector<

int>

(test_vec_swap)

.swap

(test_vec_swap)

;printf

("after swap: \ntest_vec_swap.size(): %lu\n"

, test_vec_swap.

size()

);printf

("test_vec_swap.capacity(): %lu\n"

, test_vec_swap.

capacity()

);vector<

int> int_vec0

; vector<

int> int_vec1

; vector<

int>

::iterator it_int_vec0 = int_vec0.

begin()

; vector<

int>

::iterator it_int_vec1 = int_vec1.

begin()

; it_int_vec0 = it_int_vec0 +2;

it_int_vec1 = it_int_vec1 +2;

printf

("before swap, interator status:\nit_int_vec0: %d\nit_int_vec1: %d\n"

,*it_int_vec0,

*it_int_vec1)

; int_vec0.

swap

(int_vec1)

;printf

("after swap, interator status1:\nit_int_vec0: %d\nit_int_vec1: %d\n"

,*it_int_vec0,

*it_int_vec1)

; int_vec0[2]

=999

;printf

("after swap, interator status2:\nit_int_vec0: %d\nit_int_vec1: %d\n"

,*it_int_vec0,

*it_int_vec1)

;return0;

}

編譯和執行結果

g++

-o swap_op swap_op.cpp -o0 -g -wall -std=c++11.

/swap_op

test_vec_shrink.

size()

:10test_vec_shrink.

capacity()

:16test_vec_swap.

size()

:10test_vec_swap.

capacity()

:16after shrink_to_fit:

test_vec_shrink.

size()

:10test_vec_shrink.

capacity()

:10after swap:

test_vec_swap.

size()

:10test_vec_swap.

capacity()

:10before swap, interator status:

it_int_vec0:

2it_int_vec1:

7after swap, interator status1:

it_int_vec0:

2it_int_vec1:

7after swap, interator status2:

it_int_vec0:

2it_int_vec1:

999

測試程式中vector(test_vec_swap).swap(test_vec_swap);可以理解為做了這幾件事:通過vector拷貝建構函式建立乙個test_vec_swap複本,但是僅僅複製元素,不會複製多餘的容量,之後用這個複本和原來的test_vec_swap所swap操作,操作的結果就是僅僅留下元素,不會有多餘的容量。

如果將vector(test_vec_swap).swap(test_vec_swap);替換成vector().swap(test_vec_swap);,就會新建乙個空vecotr,然後和目標做swap操作,結果就是只剩乙個空vector,沒有元素,沒有容量。

如果兩個容器做swap之後,例如測試程式中int_vec0和int_vec1,swap之前它們的迭代器it_int_vec0和it_int_vec1,swap之後依然有效,但是代表的元素交換了位置,例如int_vec0[2] = 999;之後,it_int_vec1的值變成了999,這個特性其實有些危險,不熟悉的程式設計師容易不小心改錯值。

STL容器介紹

fighting進行時 2016.1.12 2016第一彈,明天考試 壓力賊大。廢話不多說了,今天學了stl裡的vector list set map。vector是乙個是個動態的陣列,相比陣列來講,有乙個好處 因為陣列呢,是一段連續的記憶體,如果說你要用10000個吧,但是你最開始只開了100個,...

STL容器介紹

stl的容器可以分為以下幾個大類 一 序列容器,有vector,list,deque,string.二 關聯容器,有set,multiset,map,mulmap,hash set,hash map,hash multiset,hash multimap 三 其他的雜項 stack,queue,va...

關於C 容器的swap操作

一 swap操作交換兩個相同型別的容器的內容,一般的容器 除array外 交換兩個容器內容的操作會保證非常快,因為並沒有交換元素本身,而只是交換了兩個容器的內部資料結構。拿vector做個例子 include include int main std vector ivec2 std cout st...