Java의 가바지 컬렉터가 너무 당연하다고 생각해서, C++에서는 유사한 기능이 있을까 싶어 찾아보다가 이 포스팅의 키워드인 스마트 포인터에 대해 찾아보게 됐다.
스마트 포인터(smart pointer)
- C++ 프로그램에서 new 키워드를 사용하여 동적으로 할당받은 메모리는 반드시 delete 키워드를 사용하여 해제해야 한다
- C++에서는 메모리 누수(memory leak)로부터 프로그램의 안정성을 보장하기 위해 스마트 포인터를 제공하고 있다.
- 스마트 포인터란 포인터처럼 동작하는 클래스 템플릿으로 사용이 끝난 메모리를 자동으로 해제해 준다.
스마트 포인터의 동작
- 보통 new 키워드를 사용해 기본 포인터(raw pointer)가 실제 메모리를 가리키도록 초기화한 후에 기본 포인터를 스마트 포인터에 대입하여 사용한다.
- 이렇게 정의된 스마트 포인터의 수명이 다하면 소멸자는 delete 키워드를 사용하여 할당된 메모리를 자동으로 해제한다.
- 따라서 new 키워드가 반환하는 주소값을 스마트 포인터에 대입하면 따로 메모리를 해제할 필요가 없어진다.
스마트 포인터의 종류
- C++11 이전에는 auto_ptr이라는 스마트 포인터를 사용하여 이 작업을 수행했다.
- 하지만 C++11부터는 다음과 같은 새로운 스마트 포인터를 제공하고 있다.
- unique_ptr
- shared_ptr
- weak_ptr
- 스마트 포인터는 memory 헤더 파일에 정의되어 있다.
※auto_ptr은 C++11 표준부터 삭제되었다.
unique_ptr
: 하나의 스마트 포인터만이 특정 객체를 소유할 수 있도록, 객체에 소유권 개념을 도입한 스마트 포인터입니다.
해당 객체의 소유권을 가지고 있을 때만, 소멸자가 해당 객체를 삭제할 수 있다.
move() 멤버 함수를 통해 소유권을 이전할 수는 있지만, 복사할 수는 없다.
소유권이 이전되면, 이전 unique_ptr 인스턴스는 더는 해당 객체를 소유하지 않게 재설정된다.
보통의 C++ 객체에 대해 스마트 포인터가 필요한 상황에서는 주로 unique_ptr을 사용하면 된다.
C++14 이후부터 제공되는 make_unique() 함수를 사용하면 unique_ptr 인스턴스를 안전하게 생성할 수 있다.
make_unique() 함수는 전달받은 인수를 사용해 지정된 타입의 객체를 생성하고, 생성된 객체를 가리키는 unique_ptr을 반환한다.
이 함수를 사용하면, 예외 발생에 대해 안전하게 대처할 수 있다.
make_unique() 함수를 사용하기 위해서는 여러분의 C++ 컴파일러가 C++14를 지원해야 한다.
shared_ptr
: 하나의 특정 객체를 참조하는 스마트 포인터가 총 몇 개인지를 참조하는 스마트 포인터다.
이렇게 참조하고 있는 스마트 포인터의 개수를 참조 횟수(reference count)라고 한다.
참조 횟수는 특정 객체에 새로운 shared_ptr이 추가될 때마다 1씩 증가하며, 수명이 다할 때마다 1씩 감소한다.
따라서 마지막 shared_ptr의 수명이 다하여, 참조 횟수가 0이 되면 delete 키워드를 사용하여 메모리를 자동으로 해제한다.
weak_ptr
: 하나 이상의 shared_ptr 인스턴스가 소유하는 객체에 대한 접근을 제공하지만, 소유자의 수에는 포함되지 않는 스마트 포인터다.
shared_ptr은 참조 횟수(reference count)를 기반으로 동작하는 스마트 포인터다.
만약 서로가 상대방을 가리키는 shared_ptr를 가지고 있다면, 참조 횟수는 절대 0이 되지 않으므로 메모리는 영원히 해제되지 않는다.
이렇게 서로가 상대방을 참조하고 있는 상황을 순환 참조(circular reference)라고 한다.
weak_ptr은 바로 이러한 shared_ptr 인스턴스 사이의 순환 참조를 제거하기 위해서 사용된다
참고 자료 :
'Language & Framework & GIT > C++' 카테고리의 다른 글
[씨앤씨뿔] 템플릿과 함수 템플릿 (11) | 2023.06.28 |
---|---|
[씨앤씨뿔] C++ Template VS Java Generic? (4) | 2023.06.20 |
[씨앤씨뿔]C++ / 객체 포인터& 배열 & 동적 생성 - 3 (5) | 2023.04.28 |
[씨앤씨뿔] isalpha 함수 : <locale> - 3 (1) | 2023.04.28 |
[씨앤씨뿔] isdigit 함수 : <locale> - 2 (0) | 2023.04.27 |
댓글