• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    미해결

강의 22:28분경 질문있습니다

22.10.11 23:10 작성 조회수 139

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); 과 같은 코드만 썼을 경우는 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()으로 하면 정상 작동됩니다!

정상작동 버전

image

에러 버전

image

제가 보기엔 똑같아 보여서... 이게 무슨 차이인지 궁금합니다

소유권이라기 보다는 그냥 v.erase(it)을 하면,
삭제한 다음 데이터를 가리키는 iterator를 리턴합니다.
만약 하필 마지막 데이터가 삭제된다면, 사실상 v.end()를 리턴하는데
여기서 추가적으로 it++을 하니 난리가 나겠죠.

그리고 위에서 begin, end를 미리 계산한 다음, for에서 사용하면 당연히 의미가 달라집니다.
왜냐하면 erase 자체가 데이터를 제거해서 end 위치가 달라지기 때문이죠.
따라서 erase 등으로 중간 데이터가 달라질 수 있다면 v.begin(), v.end()로 하셔야 합니다.