작성
·
204
0
강의를 듣고 따라해보다가 궁금한게 생겼는데요 다음과 같이 코드를 짜면 4를 읽지않고 ++it로 5로 넘어간다는 것까지는 이해했습니다
그런데 다음 for 문을 돌리게 되면 이런 에러가 뜨면서 크래쉬가 나는데 어떤 이유인지 궁금합니다
다시 보니 제가 v.begin()을 vector<int>::iterator itBegin에 집어넣어서 사용해서 그런 것 같네요 itBegin을 v.begin()으로 바꾸니 제대로 작동합니다 그런데 그렇게 사용하면 에러가 나는 이유는 뭔가요??
답변 1
1
그게 문제가 아닙니다.
it = v.erase(it); 같은 코드가 들어가면 무조건 바로 break를 해주거나,
if (data == 3)
it = v.erase(it);
else
it++;
같은 형태로 코드가 수정되어야 합니다. (물론 for문의 it++는 제거해야하구요)
소유권이라기 보다는 그냥 v.erase(it)을 하면,
삭제한 다음 데이터를 가리키는 iterator를 리턴합니다.
만약 하필 마지막 데이터가 삭제된다면, 사실상 v.end()를 리턴하는데
여기서 추가적으로 it++을 하니 난리가 나겠죠.
그리고 위에서 begin, end를 미리 계산한 다음, for에서 사용하면 당연히 의미가 달라집니다.
왜냐하면 erase 자체가 데이터를 제거해서 end 위치가 달라지기 때문이죠.
따라서 erase 등으로 중간 데이터가 달라질 수 있다면 v.begin(), v.end()로 하셔야 합니다.
음... v.erase(it); 과 같은 코드만 썼을 경우는 erase가 it이 누구 소유인지 까지 다 날려서 break를 해줘야 하고 그게 아니라면 it = v.erase(it) 을 해서 소유권을 날려버리지 않게 해줘야 한다고 이해했습니다. 다만 it = v.erase(it)만 했을 경우에는 위 그림에서 3을 빼고 4부터 9까지 값이 앞으로 당겨지기 때문에 for 문의 ++it으로 인해 4의 데이터는 읽히지 않고 5로 바로 넘어가는 경우가 생겨
if (data == 3)
it = v.erase(it);
else
it++;
이렇게 해줘야 한다고 이해했습니다. 근데 제가 질문한 위 그림에서는 다시 해봐도 v.begin()을 vector<int>::iterator itBegin에 넣어서 사용해서 문제가 발생한 것 같은데요...ㅠㅠ
v.begin()으로 하면 정상 작동됩니다!
정상작동 버전
에러 버전
제가 보기엔 똑같아 보여서... 이게 무슨 차이인지 궁금합니다