항목 17: new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자

먼저 아래 코드를 보자.

int priority();
void processWidget(std::shared_ptr<Widget> pw, int priority);

#if 0
processWidget(new Widget, priority()); // 빌드 안됨
                                       // shared_ptr은 암시적 변환 지원 안함
#endif

processWidget(std::shared_ptr<Widget>(new Widget), priority());
1. 마지막 문장에서 processWidget을 호출하기 전에 인자 평가 순서는?

컴파일러 마다 평가하는 순서는 다르다.

  1. 인자 평가를 위한 세가지 종류의 코드는 무엇인가?

  2. priority를 호출한다.

  3. new Widget을 실행한다.

  4. shared_ptr 생성자를 호출한다.
3. 위 코드의 문제점은 뭔가?

인자 평가 순서가 아래와 같다고 가정하자.

  • new Widget 실행
  • priority 호출
  • shared_ptr 생성자 호출

이 상황에서 priority 실행중 예외가 발생되면 shared_ptr의 생성자 호출은 실행되지 않아 new Widget 에서 받은 메모리가 실종된다.(이 경우 디버깅 하기 힘듬)

4. 해결법은?

아래 코드처럼 new 부분은 독립된 한 문장으로 처리한다.

std::shared_ptr<Widget> pw(new Widget);

processWidget(pw, priority());

정리

  • new로 생성한 객체를 스마트 포인터로 넣는 코드는 별도의 한 문장으로 만들자. 이것이 안 되어 있으면, 예외가 발생될 때 디버깅하기 힘든 자원 누출이 될 수 있다.

results matching ""

    No results matching ""