- 처리 우선순위를 알려주는 함수와 동적으로 할당한 객체에 대해 우선순위에 따른 처리를 적용하는 함수가 있습니다.
동적으로 할당 되는 Customer는 tr1::shared_ptr을 이용하여 사용하도록 만들었습니다.
1
2
3
4
5
6
7
8
9
| // 처리 우선순위를 알려주는 함수 int priority(); // 우선순위에 따라 처리를 적용하는 함수 void processCustomer( std::tr1::shared_ptr<costomer> pc, int priority); { processCustomer( std::tr1::shared_ptr<costomer>( new Customer), priority() ); } |
- 위 코드는 컴파일은 잘 되지만, 자원을 흘릴 가능성이 있습니다.
- 컴파일러는 processCustomer 호출 코드를 만들기 전에 우선 이 함수의 매개변수로 넘겨지는 인자를 평가하는 순서를 밟습니다.
위 코드에서는 컴파일러가 processCustomer 함수 호출이 이루어 지기 전에 세 가지 연산을 위한 코드를 컴파일러가 만들게 됩니다.
① priority를 호출합니다.
② new Customer 를 실행합니다.
③ tr1::shared_ptr 생성자를 호출 합니다.
- 그런데, 여기서 각각의 연산이 실행되는 순서는 컴파일러 제작사마다 다르다는게 문제입니다.
① new Customer 를 실행합니다.
② priority를 호출합니다.
③ tr1::shared_ptr 생성자를 호출 합니다.
- 위의 순서대로 호출 될때, priority 함수에서 예외가 발생하면, shared_ptr에 저장 되기도 전에 발생했기 때문에,
Customer는 포인터가 유실되고, 자원 누출이 발생하게 됩니다.
[ 개선 ]
1
2
3
4
| std::tr1::shared_ptr<customer> pc( new Customer); processCustomer( pc , priority() ); </customer> |
- Customer를 생성하여 스마트 포인터에 저장하는 코드는 별도의 문장 하나로 만들고,
그 스마트 포인터를 processCustomer에 넘기는 것입니다.
그러면, 컴파일러의 재조정을 받을 여지가 적기 때문에 자원 누출 가능성이 없습니다.
* new로 생성한 객체를 스마트 포인터로 넣는 코드는 별도의 한 문장으로 만듭시다.
이것이 안 되어 있으면, 예외가 발생될 때 디버깅하기 힘든 자원 누출이 초래될 수 있습니다.
댓글 없음:
댓글 쓰기