new로 생성한 객체를 스마트 포인터에 저장하는

코드는 별도의 한 문장으로 만들자.


처리 우선순위를 알려 주는 함수가 있고,

동적으로 할당한 Data 객체에 대해 어떤

우선 순위에 따라 처리를 적용하는 함수가 있다.


int p();

void processData ( shared_ptr<Data> pd, int p );


1. processData (new Data, p);

--> 컴파일 오류가 난다.

shared_ptr의 생성자는 explicit으로

선언 되어 있기 때문에, 'new Data' 라는

표현식에 의해 만들어진 포인터가

shared_ptr 타입의 객체로 바꾸는

암시적인 변환이 가능할 수 없다.


2. pricessData( shared_ptr<Data>(new Data) , p());

--> 정상적으로 동작한다.




컴파일러는 processData 호출 코드를 만들기 전에

이 함수의 매개변수로 넘겨지는 인자를 평가 한다.

첫 번째 인자 shared_ptr<Data>(new Data)는

1. new Data 표현식을 실행하는 부분과

2. shared_ptr 생성자를 호출하는 부분으로 나눠진다.




따라서 processData 함수 호출이 이루어지기 전에

컴파일러는 다음의 세 가지 연산을 위한 코드를 만든다.


1. p를 호출.

2. new Data를 실행.

3. shared_ptr 생성자 호출.


하지만 각각의 연상이 실행되는 순서는

컴파일러마다 다르다는게 문제점이다.

따라서 new Data 부분이 shared_ptr보다 먼저

호출되어야 하지만 이 부분을 장담할 수 없다.




1. new Data를 실행.

2. p를 호출.

3. shared_ptr 생성자 호출.


위와 같이 실행이 되도 문제가 생길 수 있다.

p를 호출하는 부분에 예외가 발생했다면

new Data로 만들어졌던 포인터가 유실될 수 있다.




해결책

Data를 생성해서 스마트 포인터에

저장하는 코드를 별도의 문장 하나로 만들고,

그 스마트 포인터를 processData에 넘기는 것이다.


shared_ptr<Dara> pd(new Data);

--> new로 생성한 객체를 스마트 포인터에

담는 코드를 하나의 독립정인 문장으로 만든다.

processData(pd, p());

--> 인자의 평가 순서가 바뀌어도

자원 누출의 가능성이 없다.




POINT!!

new로 생성한 객체를 스마트 포인터로 넣는 코드는

별도의 한 문장으로 만들자. 이것이 안 되어 있으면,

예외가 발생될 때 디버깅하기 힘든 자원 누출이 초래될 수 있다.



+ Recent posts