달력

32024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
글쎄 한동안 잘 사용해오던 

STL의  remove_if와 unique 함수의 버그(?)같은 것을 찾았다.

둘다 특정 조건에 부합되는 부분을 일정 위치 이후로 옮기고, 그 위치를 리턴 하는 방식으로 데이터를 정리할 때 사용한다.

// 일반적으로 아래와 같이 사용을 한다.
std::vector<int> vecAny;

std::vector<int>::iterator it = std::remove_if( vecAny.begin(), vecAny.end(), ANYFunction );
if( it !=  vecAny.end() )
{
     vecAny.erase( it,  vecAny.end() );
}

그런데 이 놈의 것이 헛질거리를 하는 것을 본 것이 
std::vector<ANY_InstancePointerPOINTER> vecAny;
  std::vector<int>::iterator it = std::remove_if( vecAny.begin(), vecAny.end(), ANYFunction );
if( it !=  vecAny.end() )
{
    std::for_each( it,   vecAny.end(), _ANY_INSTANCE_REMOVE );
    vecAny.erase( it,  vecAny.end() );
}

위와 같이 잘 쓰고 있었다. 그런데.

이넘이 엄한 짓을 하고 있었다.

remove_if 시 정렬이 it가 가리키고 있는 곳과 잘 정리해서 준줄 알았는데, 주소값을 보면 중복적으로 처리되어 있는 부분이 있다.

즉. std::for_each를 이용해서 삭제를 할 경우 실제 instance가 앞쪽에 정렬되어 있는 넘과 같아서 남아 있어야 할 넘이 지워지는 경우까지 발생했다.

이와 같은 문제는 std::unique에서도 동일하게 발견되었다.

이 넘들 땜시 갑자기 죽어나가는 상황을 찾느라... ㅠ.ㅠ

결국 앞의 remove_if는 방법을 바꿔서 처리했다.

// 기존 방식
std::vector<int>::iterator it = std::remove_if( vecAny.begin(), vecAny.end(), ANYFunction );
if( it !=  vecAny.end() )
{
     vecAny.erase( it,  vecAny.end() );
}

// 문제 회피 방식
std::vector<int>::iterator it = std::find_if( vecAny.begin(), vecAny.end(), ANYFunction ); 
while(  it  !=  vecAny.end() )
{
   delete *it;
   vecAny.erase(it);
   if( vecAny.empty() == true ) break;

    it = std::find_if( vecAny.begin(), vecAny.end(), ANYFunction ); 
}

// unique의 경우는 보다 길어 졌다.
Dummy로 한쪽으로 옮겨놓고 원래 Container로 unique하게 만들때, 일일이 검사하는 방법으로 처리했다..
길어서 내용은 봐서~~ 나중에.. 

여하튼 참 고민스럽게 만든 부분들 이었다..

 
Posted by 촌돌애비
|