본문 바로가기
카테고리 없음

C++ vector 의 erase 사용시 참고사항

by MY블로그 2022. 11. 18.

 

C++ vector 의 erase 사용시 참고사항 < 예시 : 다수 가위 바위 보 게임의 코드 참고 >
	for (vector< RPlayer>::iterator it = players.begin(); it != players.end();)
		{  
			if ((*it).result == LOSE) 
			{
				it = players.erase(it); 
				
			}
			else
			{
				it++; 
			}
		}

오늘은 수업 과제 중에서 아주 중요한 부분이 있어 따로 복습하기 위해 글을 쓰게되었다.

위의 코드는 다수가위바위보 게임의 코드의 일부분이다.

이부분에는 vector 그리고 erase 가 사용이된다.

가위바위보에서 패배한 플레이어가 배열에서 빠지게되는 코드인데

단순히 vector로 할당된 배열에서 패배 배열을 제거하는경우 일정 조건에서 문제가 발생한다.

 

문제란 만일 5명의플레이어가있고 플레이어의 순서대로

[0] 배열 [1] 배열 [2] 배열 [3] 배열 [4] 배열
패배 패배

이런식으로 승패의 결과가 나왔다고 보자.

단순히 포문으로 처음배열(begin) 부터 (!end/끝아닌부분까지(끝부분은 NULL이다/지난번공부참고))

검사를하고 제일번저 패배가있는 [1]배열 부분을 제거할것이다.

[0] 배열 [1] 배열 [2] 배열 [3] 배열
패배

위를보자면 [1]배열에있던 패배가 빠지고 2번배열의패배가 [1]배열로 당겨졌다.

이런경우 컴퓨터는 [1]배열의 패배를 제거하는 작업을 마쳤으니 바로 [2]배열의 검사가 진행될것이다.

그렇게된다면 원래 [2]배열에 있다가 [1]배열에 당겨지며 배치된 패배는 제거 검사에서 제외가된다.

때문에 단순히 포문에서 ++ 증가시키며 검사시키게된다면 위와같은 오류가 발생될수가있다.

(제거후 출력시 승자만떠야되는데 당겨져오면서 제거에서 제외된 패배 배열이 같이출력된다)

 

이런 부분을 주의해야하며 해결 방법으로는 위의 코드를 보면 된다.

 

중요 !! iterator 이터는 포인터 같은 사용을한다!! 즉, 주소를 가리킨다 !!

	for (vector< RPlayer>::iterator it = players.begin(); it != players.end();)
		{  // erase의 반환값은 iterator 이다! 때문에 이터의 조건은
          // it = 임의로 정한 변수의 이름이다.
          // 플레이어배열의 시작부분(it = players.begin();) 부터
          // 플레이어배열의 Null부분이아닌 배열끝(it!=players.end();)까지
          // 검사조건을 걸고
			if ((*it).result == LOSE)  // it의 주소의.승패값이 == 패배 라면
			{
				it = players.erase(it); 
				// it 자리는 erase(제거) 하고 제거된자리를 it으로 한다.
                // 이부분이 정말 이해하기 어렵다.. 
                // 정의한부분을 제거된부분에 재정의 하는듯하다.
                // 일단 외워두자.
			}
			else // 검사후 지워야되는부분이아니면 주소를 +1 시켜검사한다.
			{ 
				it++; 
			}
		}

 

댓글