C++

std::copy()를 사용할 때 하기 쉬운 실수

곽곽 2022. 9. 20. 18:20
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    string str="abcde", rev_str;
    copy(str.begin(), str.end(), rev_str.begin());
    cout<<rev_str<<endl;

    return 0;
}

위와 같은 코드를 실행했다고 해보자. 어떤 결과가 나올까?

abcde 를 기대했다면 오산이다. 결과값이 나오지 않는다!

그렇다면 왜 이런 결과가 나오는 것일까? 같은 문제를 vector를 사용하여 비교해보자.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> v={1,2,3,4,5}, rev_v(5);
    copy(v.begin(), v.end(), rev_v.begin());
    for(auto it:rev_v) {
        cout<<it;
    }

    return 0;
}

이 경우에는 바라던 대로 abcde로 올바른 결과를 얻을 수 있다.

그렇다면 위와 아래에는 어떤 차이점이 있는 것일까?

copy()가 string에서는 동작하지 않기 때문일까?

답은 공간이 있느냐 없느냐이다.

아래 코드에서 rev_v는 먼저 크기를 5로 할당해줬다. 그렇기 때문에 맨 앞 iterator를 가지고 5개의 value를 copy할 수 있는 것이다.

반면에, 위의 코드에서 rev_str는 지금 크기가 0이다.

5개의 값을 넣어줄 공간이 부족하기 때문에 copy를 해도 그 값을 넣어줄 공간이 없는 것이다.

즉, 올바르게 copy를 수행하기 위해서는 rev_str에 5보다 크거나 같은 크기를 할당을 먼저 해줘야 한다.

rev_str.resize()=str.size()를 해주거나 rev_str을 크기가 5 이상인 string으로 초기화해주면 쉽게 이 문제를 해결해줄 수 있다.

이 문제는 string에만 국한된 것이 아니고, vector에서도 할당해준 크기가 부족할 경우에도 마찬가지로 발생할 수 있으니 copy()를 사용할 때는 먼저 그 값을 붙여줄 공간이 있는지 먼저 확인해줘야 한다.