글쎄 한동안 잘 사용해오던
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하게 만들때, 일일이 검사하는 방법으로 처리했다..
길어서 내용은 봐서~~ 나중에..
여하튼 참 고민스럽게 만든 부분들 이었다..
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하게 만들때, 일일이 검사하는 방법으로 처리했다..
길어서 내용은 봐서~~ 나중에..
여하튼 참 고민스럽게 만든 부분들 이었다..
'삽질' 카테고리의 다른 글
[펌] expdp/impdp 사용 예 및 help 사용 법 (0) | 2012.07.04 |
---|---|
Oracle Primary key 별도의 table space에 설정. (0) | 2012.06.28 |
Visual Studio 로 컴파일 할 때 "이 프로젝트는 만료되었습니다." (2) | 2012.02.16 |
메모리 Leak을 체크하는 방법 MSDN.... (0) | 2012.02.16 |
ORA-12516: TNS:listener could not find available handler (0) | 2012.02.09 |
|
댓글0
댓글을 달아 주세요