2016-11-23 52 views
0

我有以下的玩具例子:理解的std ::交換兩個指針和std ::向量

#include<iostream> 
#include<vector> 


int main(){ 


    std::vector<int> a={1, 2, 3}; 
    std::vector<int> b={4, 5, 6}; 

    int* pa = a.data(); 
    int* pb = b.data(); 

    std::swap(pa,pb); 
    std::cout<<"after std::swap(pa,pb)\n"; 
    std::cout<<"a= "<<a[0]<<" "<<a[1]<<" "<<a[2]<<"\n"; 
    std::cout<<"b= "<<b[0]<<" "<<b[1]<<" "<<b[2]<<"\n"; 

    std::cout<<"pa= "<<pa[0]<<" "<<pa[1]<<" "<<pa[2]<<"\n"; 
    std::cout<<"pb= "<<pb[0]<<" "<<pb[1]<<" "<<pb[2]<<"\n"; 

    std::swap(a,b); 

    std::cout<<"after std::swap(a,b)\n"; 
    std::cout<<"a= "<<a[0]<<" "<<a[1]<<" "<<a[2]<<"\n"; 
    std::cout<<"b= "<<b[0]<<" "<<b[1]<<" "<<b[2]<<"\n"; 

    std::cout<<"pa= "<<pa[0]<<" "<<pa[1]<<" "<<pa[2]<<"\n"; 
    std::cout<<"pb= "<<pb[0]<<" "<<pb[1]<<" "<<pb[2]<<"\n"; 
} 

交換後會發生什麼(PA,PB)我很清楚,我希望PA點到b .data(),但是在swap(a,b)之後,我希望b.data()現在指向「1 2 3」,但打印出pa [0],pa [1],pa時不是這種情況[2] ...

+0

我不認爲你可以(合法)通過舊的'.data()'指針訪問數據後移動它 –

+0

@appleapple是的,你可以,移動後容器仍處於有效但未定義的狀態 –

+0

@GuillaumeRacicot如果它是未定義狀態,爲什麼老''。data()'指針保持有效? –

回答

2

http://en.cppreference.com/w/cpp/container/vector/swap注意到:

所有迭代器和引用仍然有效。過去的最終迭代器失效。

這意味着存儲器分配留相同,矢量場交換

std::vector<int> a={1, 2, 3}; // data lays at pa 
    std::vector<int> b={4, 5, 6}; // data lays at pb 

    int* c = a.data(); // == pa 
    int* d = b.data(); // == pb 

    std::swap(c,d); // c == pb, d == pa 
    std::cout<<"after std::swap(c,d)\n"; 
    std::cout<<"a= "<<a[0]<<" "<<a[1]<<" "<<a[2]<<"\n"; 
    std::cout<<"b= "<<b[0]<<" "<<b[1]<<" "<<b[2]<<"\n"; 

    std::cout<<"c= "<<c[0]<<" "<<c[1]<<" "<<c[2]<<"\n"; 
    std::cout<<"d= "<<d[0]<<" "<<d[1]<<" "<<d[2]<<"\n"; 

    std::swap(a,b); // c == pb, d == pa, a == pb, b == pa 

    std::cout<<"after std::swap(a,b)\n"; 
    std::cout<<"a= "<<a[0]<<" "<<a[1]<<" "<<a[2]<<"\n"; 
    std::cout<<"b= "<<b[0]<<" "<<b[1]<<" "<<b[2]<<"\n"; 

    std::cout<<"c= "<<c[0]<<" "<<c[1]<<" "<<c[2]<<"\n"; 
    std::cout<<"d= "<<d[0]<<" "<<d[1]<<" "<<d[2]<<"\n"; 
0

載體趨於具有指向數據的指針來實現。所以,讓我們說有在內存中調用foo一個地方{1, 2, 3}bar{4, 5, 6}

std::vector<int> a={1, 2, 3}; 
std::vector<int> b={4, 5, 6}; 

a起始位置起始位置是有一個指向指針的向量foo
b是具有指向bar

int* c = a.data(); 
int* d = b.data(); 
指針的載體

c是指向a的指針當前指向的指針; foo
d是一個指針,指向b的指針當前指向的內容; bar

現在,讓我們做一些交換...

std::swap(c, d); 

c是一個指針現在指向什麼d指着; bar
d是一個指針,指向c指向的內容; foo
所以c現在將指向{4, 5, 6}d現在將指向{1, 2, 3}

std::swap(a, b); 

a的指針現在指向什麼b的指針指着; bar
b的指針現在指向a的指針指向的內容; foo
交換向量交換他們指向的東西;它不會交換內部的實際數據。