C++STL中swap函数操作与内存地址改变的简析
寫在前面
這篇文章主要討論了STL中swap函數在交換2個容器的內容的時候是交換內存還是交換元素的問題。由于博主對C++的學習并不好,如果有什么錯誤懇請大家提出。下面會有一些代碼展示一下swap函數在對容器進行交換的時候對內存地址的影響,感興趣的同學也可以自己寫一下代碼,會更加直觀理解swap函數。
先放結論
swap函數會交換2個數據類型相同的容器內容。本身交換的速度非???#xff0c;因為swap在交換的時候并不是完全將2個容器的元素互換,而是交換了2個容器內的內存地址。除了數組,其他容器在交換后本質上是將內存地址進行了交換,而元素本身在內存中的位置是沒有變化的。換而言之,如果說有2個房間,名字是a和b,那么swap函數交換的是2個房間的名字,而房間里的物品根本沒有任何移動。那么外部指向物品的指針當然也沒有任何變化,原來指向物品A的,swap交換后仍然指向物品A。而對于數組,
對vector使用swap函數
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
?
using namespace std;
?
int main() {
?? ?int a[3] = { 1,2,3 };
?? ?int b[3] = { 4,5,6 };
?? ?vector<int> v1(a, a + 3);
?? ?vector<int> v2(b, b + 3);
?? ?cout << "v1中各個元素的地址:" << endl;
?? ?for (int i = 0; i < 3; i++) {
?? ??? ?cout << &v1[i] << " ";
?? ?}
?? ?cout ?<< endl << "v2中各個元素的地址:" << endl;
?? ?for (int i = 0; i < 3; i++) {
?? ??? ?cout << &v2[i] << " ";
?? ?}
?? ?int *temp = &v1[2];
?? ?cout << endl << "temp指針指向的數據值:" << endl << *temp;
?? ?cout << endl << endl;
?? ?swap(v1, v2);
?? ?cout << "v1中各個元素的地址:" << endl;
?? ?for (int i = 0; i < 3; i++) {
?? ??? ?cout << &v1[i] << " ";
?? ?}
?? ?cout << endl << "v2中各個元素的地址:" << endl;
?? ?for (int i = 0; i < 3; i++) {
?? ??? ?cout << &v2[i] << " ";
?? ?}
?? ?cout << endl << "temp指針指向的數據值:" << endl << *temp;
?? ?cout << endl;
?
?? ?system("pause");
?? ?return 0;
}
下面是在博主計算機上的運行結果:
可以看出,v1與v2的各個元素的地址進行了交換,換而言之就是v1與v2的“名字”進行了交換,而里面的元素該在什么地址仍然在什么地址。
對數組使用swap函數
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
?
using namespace std;
?
int main() {
?? ?int a[3] = { 1,2,3 };
?? ?int b[3] = { 4,5,6 };
?? ?cout << "a數組中各個元素的地址:" << endl;
?? ?for (int i = 0; i < 3; i++) {
?? ??? ?cout << a + i << " ";
?? ?}
?? ?cout << endl << "b數組中各個元素的地址:" << endl;
?? ?for (int i = 0; i < 3; i++) {
?? ??? ?cout << b + i << " ";
?? ?}
?? ?int *temp = a + 2;
?? ?cout << endl << "temp指針指向的數據值:" << endl << *temp;
?? ?cout << endl << endl;
?? ?swap(a, b);
?? ?cout << "a數組中各個元素的地址:" << endl;
?? ?for (int i = 0; i < 3; i++) {
?? ??? ?cout << a + i << " ";
?? ?}
?? ?cout << endl << "b數組中各個元素的地址:" << endl;
?? ?for (int i = 0; i < 3; i++) {
?? ??? ?cout << b + i << " ";
?? ?}
?? ?cout << endl << "temp指針指向的數據值:" << endl << *temp;
?? ?cout << endl;
?
?? ?system("pause");
?? ?return 0;
}
下面仍然是在博主計算機上運行的結果:
可以看到,對數組進行swap交換后,地址是不變的,也就是說,對于數組,swap函數老老實實將所有的元素進行了交換。房間名不變,將里面的物品交換了位置。對于temp指針而言,temp指向的地址永遠是不變的,但是由于交換了元素,所以temp指向的內存地址的數據發生了變化??梢岳斫鉃閍房間是海爾飲水機,b房間是三星飲水機,temp指向的永遠是a房間的飲水機,那么swap交換后,a房間的飲水機變成了三星的,那么temp指向的當然也變成三星飲水機了。
string
以下內容是之前不知道在哪里看的,因為博主不是搞C++的,當時參考的其他內容,并沒有過于深究準確性,因為解決了個人問題,所以認為是正確的了。但是不夠嚴謹,推薦大家專門看一下string的源碼或者咨詢其他搞C++的大佬。歡迎大家看下面的內容,有錯誤的地方可以評論改正。
string是比較特殊的,因為string的底層實現比較特殊。博主水平不夠,就只能參考其他大佬的解釋口胡了。
string在調用swap后,迭代器、引用、指針都會失效。因為string的內部實現并不是像C語言自己寫的char數組,而是用_Ptr這個指針來儲存字符串,指向的是字符串的首地址。字符串是儲存在臨時內存區域中的,也就是說,在進行交換后,內存會重新分配。所以之前的指針、迭代器等都會失效,因為它們指向的內存地址并不會隨著字符串的改變而改變。
關于_Ptr這個指針,我的理解是指向字符串的內存開始,可以參考下面這個代碼:
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
?
using namespace std;
?
int main() {
?? ?string a = "abc";
?? ?string b = "def";
?? ?for (int i = 0; i < 3; i++) {
?? ??? ?cout << &a[i] << " ";
?? ?}
?? ?cout << endl;
?? ?for (int i = 0; i < 3; i++) {
?? ??? ?cout << &b[i] << " ";
?? ?}
?? ?cout << endl << endl;
?? ?swap(a, b);
?? ?for (int i = 0; i < 3; i++) {
?? ??? ?cout << &a[i] << " ";
?? ?}
?? ?cout << endl;
?? ?for (int i = 0; i < 3; i++) {
?? ??? ?cout << &b[i] << " ";
?? ?}
?? ?cout << endl;
?
?? ?system("pause");
?? ?return 0;
}
而運行結果如下:
并不是想象中的給出內存地址,而是給出了3個字符串,因為這里得到的是_Ptr指針的內容,所以返回的是3個字符串。
?
總結
以上是生活随笔為你收集整理的C++STL中swap函数操作与内存地址改变的简析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: const_iterator简单介绍
- 下一篇: xhtml文件的后缀名是什么?