언어/Effective C++

[Effective C++] #17 자원 관리 객체와 new 사용

Hardii2 2022. 1. 17. 11:51

[Effective C++] #17 자원 관리 객체와 new 사용

 

Scott Meyers의 "Effective C++" 통해, C++ 구현에 필요한 개념들을 이해하고, 기록하기 위함입니다. 해당 항목은 3장 "자원 관리", 항목 17 "new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자"에 해당하는 내용입니다.

 

 


 

자원 관리 객체의 메모리 동적 할당
void someFunc (std::tr1::shared_ptr<A_클래스>, int priority){
    ...
};

int priority = 1;

someFunc(std::tr1::shared_ptr<A_클래스>(new A_클래스), priority);

위 예제 코드는 동적으로 할당받은 A_클래스 객체에 대한 자원 관리 객체(shared_ptr)와 정수형 변수를 인자로 받는 함수를 구현합니다. 자원 관리 객체에 대한 자세한 내용은 아래 링크를 살펴보시기 바랍니다. 위 코드의 경우 컴파일은되지만, 문제가 존재합니다. 컴파일러는 someFunc 함수 호출 전 인자들을 평가하는 순서를 가집니다. 첫 번째 인자는 두 부분으로 나누어지는데, std::tr1::shared_ptr의 생성자 호출 부분과 new A_클래스를 통한 동적 할당 실행 부분입니다. 따라서 someFunc 함수가 정상적으로 실행되기 위해 컴파일러는 new A_클래스의 메모리 동적 할당, shared_ptr의 생성자 호출, 그리고 priority 변수 호출을 수행해야 합니다. 이때, "std::tr1::shared_ptr <A_클래스> (new A_클래스)"의 경우 메모리 동적 호출 연산이 선제적으로 수행되어야 합니다. 그 이유는 자원 관리 객체의 생성자 호출을 위해 우선적으로 A_클래스 객체에 대한 정보가 필요하기 때문이죠. 추가적으로, "new A_클래스"를 통해 생성한 자원이 자원 관리 객체로 넘어가는 시점에 발생하는 예외는 자원 누출의 위험 또한 내포합니다. 그 이유는 "priority" 변수의 호출 또한 순서가 정해져 있지 않아, "new A_클래스" -> "priority" -> "std::tr1::shared_ptr <A_클래스>"의 순서는 A_클래스 자원을 자원 관리 객체(shared_ptr)에게 넘기기 전에 발생하는 예외에 취약하다는 것을 의미합니다. 따라서, A_클래스를 생성해서 자원 관리 객체에게 넘기는 코드를 별도로 작성하고, 자원 관리 객체를 함수의 인자로 넘기는 방법이 더 안전합니다.

 

[Effective C++] #13 자원 관리 객체, std::auto_ptr, std::shared_ptr

[Effective C++] #13 자원 관리 객체, std::auto_ptr, std::shared_ptr Scott Meyers의 "Effective C++"를 통해, C++ 구현에 필요한 개념들을 이해하고, 기록하기 위함입니다. 해당 항목은 3장 "자원 관리", 항..

webddevys.tistory.com

std::tr1::shared_ptr<A_클래스> ptr (new A_클래스);
int priority();

someFunc (ptr, priority());

위와 예제 코드가 자원 누출을 방지하는 더욱 효과적인 코드 작성 방법입니다. 

 

new로 생성한 객체를 자원 관리 객체에 넘기는 코드는 별도로 작성합시다.