일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 게임
- 스마트 포인터
- implicit conversion
- operator new
- 암시적 변환
- resource management class
- 메타테이블
- more effective c++
- effective stl
- virtual function
- 참조자
- 영화
- 티스토리챌린지
- 다형성
- lua
- 루아
- 함수 객체
- exception
- 예외
- 오블완
- 언리얼
- Effective c++
- 반복자
- 비교 함수 객체
- 영화 리뷰
- Smart Pointer
- 상속
- c++
- reference
- UE4
Archives
- Today
- Total
스토리텔링 개발자
[Effective STL] 33. 포인터 요소에 remove 알고리즘 사용 주의하기 본문
728x90
항목 33. remove와 비슷한 알고리즘을 포인터의 컨테이너에 적용할 때에는 각별히 조심하자
포인터 요소 제거
- 품질 보증 함수를 기준으로 벡터의 Widget 포인터 요소를 삭제하는 코드
class Widget
{
public:
...
bool isCertified() const; // Widget의 품질이 확실한가
...
};
vector<Widget*> v;
...
v.push_back(new Widget);
...
// 품질 보증이 되지 않은 Widget 객체 삭제
// mem_fun(항목 41 참조)
v.erase(remove_if(v.begin(), v.end(), not1(mem_fun(&Widget::isCertified))), v.end());
- 만약 remove_if 호출 전 상황이 아래와 같다면
- remove_if 호출 후에는 아래와 같이 될 것이다.
- 여기에 erase까지 호출된다면 아래와 같이 될 것이다.
- WidgetB와 WidgetC는 delete가 되지 않고 포인터를 잃어버렸다.
- 즉, 리소스 누수가 발생한다.
- 결국, 포인터에 대해서는 remove와 흡사한 알고리즘은 리소스 누수를 유발한다는 결론.
- 대신 partition 알고리즘(항목 31 참조)을 사용하면 될 것이다.
remove 알고리즘을 굳이 사용하고자 한다면
- 방법 1 : erase-remove 를 호출하기 전에 포인터를 delete하고 nullptr로 셋팅하기
void delAndNullifyUncertified(Widget*& pWidget)
{
if(!pWidget->isCertified())
{
delete pWidget;
pWidget = nullptr;
}
}
// 보증되지 않은 객체 널 포인터 셋팅
for_each(v.begin(), v.end(), delAndNullifyUncertified);
// 널 포인터 제거
v.erase(remove(v.begin(), v.end(), nullptr), v.end());
- 하지만 이 코드는, 불필요한 널 포인터는 가지지 않는다는 가정하에 만든 것이라는 단점이 있다.
- 방법 2 : 스마트 포인터 사용
vector< shared_ptr<Widget> > v;
...
v.push_back(make_shared<Widget>(new Widget)); // 스마트 포인터 사용
...
// 누수 없이 remove-erase를 사용할 수 있다.
v.erase(remove_if(v.begin(), v.end(), not1(mem_fun(&Widget::isCertified))), v.end();
- 대신 스마트 포인터가 Widget*으로 자동 변환을 지원해 주어야 한다.
- 호출되는 멤버 함수(Widget::isCertified)가 내장 포인터를 요구하기 때문이다.
728x90
'개발 > Effective STL' 카테고리의 다른 글
[Effective STL] 35. 대소문자 구분하지 않는 법 (0) | 2024.12.24 |
---|---|
[Effective STL] 34. 정렬된 범위에 동작하는 알고리즘 (0) | 2024.12.23 |
[Effective STL] 32. remove-erase 관용구 (0) | 2024.12.19 |
[Effective STL] 31. 상황별 정렬 선택하기 (0) | 2024.12.18 |
[Effective STL] 30. 알고리즘 사용 시 목적지 범위(destination range) 주의 (0) | 2024.12.17 |
Comments