게임을 만들던 도중  STL list로 관리하는 오브젝트가 삭제될때 list 오류가 나는것이다.. 


나는 list를 잘 사용을 못해 진짜 꼼수로 오류를 막았는데 그 방법이



오류코드

for (auto Iter : m_objects)

{

for (auto Iter02 = (*Iter.second).begin(); Iter02 != (*Iter.second).end();)

{

if ((*Iter02)->GetDelete())

{

SAFE_DELETE(*Iter02);

         (Iter.second)->erase(Iter02);

}

else

Iter02++;

}

}

여기서 m_objects는 STL map 이다. map<int key, list<cGameObject*>*> 이런 방식이다

예를 들면

 



위 코드의 문제는 만약 GetDelete함수가 참이되는 오브젝트를 삭제하고나면 그 Iter02는 삭제되어 다음 object를 가르키는 iterator가 없어지는 것이다 그리고 나서 삭제된 Iterator의 접근하니 오류가 날 수 밖에 없는 코드이다

 

 나는 list를 잘몰랐기 때문에 하나를 삭제하고 break 를 써서 안쪽 루프를 탈출하는 방법을 쓰고있었다.


바로 이렇게


꼼수식 해결코드(꼼수라고도 못한다)

for (auto Iter : m_objects)

{

for (auto Iter02 = (*Iter.second).begin(); Iter02 != (*Iter.second).end();)

{

if ((*Iter02)->GetDelete())

{

SAFE_DELETE(*Iter02);

         (Iter.second)->erase(Iter02);

 break;

}

else

Iter02++;

}

}


위 코드는 문제하나가있다 하나가 삭제될때마다 삭제된 오브젝트와 같은 key값의 list의 저장되는 object들은 현재 프레임에서 삭제를 못하고 다음 프레임에서 삭제를 해야하는 경우가 발생한다.(그냥 삭제된 오브젝트와 같은 키값 list의 저장된 오브젝트는 삭제를 계속 미루는 것이다 이게 계속 쌓여서 삭제가 느리게되는것이다.

이 문제는 내가 뭔가 위 코드가 이상하다고 느껴서 총알 발사 속도를 엄청나게 빠르게해놓고 계속 발사하다보닌까 삭제가 늦게되는 총알이 발생한다는것을 알게되었다.


인터넷의 이유를 검색하닌까 이유를 알게되었다 그 이유는


위에서도 설명했지만 삭제가 실행되는 Iterator가 삭제되면 다음 값을 가르키는 Iterator가 삭제되는 것이기 때문에 다음값의 접근을못하고 삭제된 iterator의 접근을해서 오류가 나는것이다.


이것의 해결방법은 

만약 list.erase() 를 이용하여 삭제되면 erase함수는 삭제된 Iterator의 다음 Iterator를 리턴한다. 이것을 이용하면


for (auto Iter : m_objects)

{

for (auto Iter02 = (*Iter.second).begin(); Iter02 != (*Iter.second).end();)

{

if ((*Iter02)->GetDelete())

{

SAFE_DELETE(*Iter02);

         Iter02 = (Iter.second)->erase(Iter02);

}

else

Iter02++;

}

}



이렇게만 해주면 삭제할때마다 break를 써서 탈출하여 삭제할 오브젝가 쌓이지 않고 계속 삭제된 오브젝트와 같은 list의 저장된 object들도 조건이 참이되면 계속 삭제가 될 수 있다.




개인이 공부하는 목적으로 올린 포스트이기 때문에 틀린 내용이 있을 수도 있습니다 댓글로 알려주세요



'programing > c_c++' 카테고리의 다른 글

Win32프로젝트에서 콘솔창 이용하기  (0) 2018.02.15

+ Recent posts