2016-11-23 3 views
0

나는 다음과 같은 장난감의 예를 가지고 :이해 표준 : 스왑

스왑 후 어떻게됩니까
#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(), 스왑 (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 노트 그 :

모든 반복자 및 참조는 유효합니다. past-the-end 반복자는 무효화됩니다. 메모리 할당이 동일하게 유지 수단

, 벡터 필드는 벡터 데이터에 대한 포인터로 구현되는 경향

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}{4, 5, 6}

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

a의 시작 위치입니다 bar의 시작 위치를 가리키는 포인터를 가진 벡터이다가 말을하자
bfoobar

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
벡터 교환은 그들이 가리키는 것을 서로 바꿉니다. 그것은 내부의 실제 데이터를 교환하지 않습니다.