너무 오랜만에 포스팅을 하게 되어 죄송합니다.
그동안 개인적인 사정으로 잠시 포스팅을 멈추게 되었습니다.
일이 잘 해결되어 이제 다시 포스팅을 시작하겠습니다.
1) 스마트 포인터란?
이름에서 알 수 있듯이, 스마트 포인터는 기존의 포인터에 포인터를 관리하는 추가적인 요소들을 섞어주는 것을 말합니다.
즉, 일반적인 포인터보다 더 많은 역할을 수행하는 포인터를 스마트 포인터라고 할 수 있습니다.
그리고 현대의 C++에서는 포인터를 사용하기보다는 스마트 포인터를 사용할 것을 권장합니다.
이는 C++ 기반의 게임 엔진인 언리얼 엔진도 마찬가지인데,
언리얼 엔진에서는 C++을 사용할 때는 스마트 포인터를, 언리얼 C++에서는 가비지 컬렉터를 사용합니다.
그렇다면, 왜 스마트 포인터를 사용하는 것일까요?
그것은 포인터의 한계에 있습니다.
p2는 delete되어 더 이상 존재하지 않는 상태가 되었지만,
p1의 포인터는 그것을 인식하지 못하고 p2를 참조하게 됩니다.
다시 말해, 일반적인 포인터는 포인터가 참조하고 있는 대상이 살아있는지 여부를 판단하기가 힘듭니다.
그리고 이 점에서 일반적인 포인터가 가지고 있는 위험한 점이 드러납니다.
delete된 메모리 주소가 아닌 엉뚱한 메모리의 주소를 참조하게 되어 메모리 오염을 일으키게 됩니다.
이런 이유로 현대의 C++은 스마트 포인터의 사용을 권장합니다.
2) 스마트 포인터 - shared_ptr
스마트 포인터는 크게 3가지로 분류할 수 있습니다.
- shared_ptr
- weak_ptr
- unique_ptr
그리고 이번 포스팅에서는 shared_ptr을 설명드리겠습니다.
shared_ptr은 내부적으로 refCount를 사용하여 가리키는 대상의 참조 횟수를 기록합니다.
refCount가 0이 되면 자동적으로 delete를 하게 되고, 참조 횟수가 증가하거나 감소하면 그만큼 refCount를 가감합니다.
이렇듯, shared_ptr은 내부적으로 refCount를 집계하여 포인터의 참조 대상이 살아있는지 여부를 알 수 있습니다.
그리고 shared_ptr을 통해 메모리를 더 안전하게 사용할 수 있습니다.
3) shared_ptr의 추가적인 정보
위의 코드에서 볼 수 있듯이, shard_ptr에 대해서는 추가적인 규칙이 존재합니다.
첫번째로, 한번 shared_ptr로 사용되었다면 그 이후에도 shared_ptr로 사용해야 합니다.
TargetPtr로 지정하기 위해 Player를 참조하는 shared_ptr을 만들어주었습니다.
두번째로, shared_ptr은 소멸 시점을 조정해줄 수 없습니다.
refCount가 0이 되지 않는 이상 소멸시킬 수 없으므로, 자유로운 소멸이 힘들다는 단점이 존재합니다.
세번째로, shared_ptr을 매개변수로 넘기는 경우 &(참조연산자)를 통한 참조를 넘겨주는 것이 좋습니다.
복사 방식을 사용하는 경우, refCount를 1 증가하고 구문이 끝나면 다시 1 감소하는 연산에 대한 시간이 소모됩니다.
따라서 매개변수로 넘기는 경우에는 &를 통해 원본을 넘김으로써 불필요한 연산을 줄이는 것이 좋습니다.
마지막으로, refCount은 Thread_Safety가 보장됩니다.
Thread_Safety가 보장된다는 것은 여러 스레드가 동시에 접근해도 프로그램의 실행에 문제가 없음을 의미합니다.
즉, 여러 스레드가 동시에 접근하여 한번에 무수히 많은 refCount의 증가가 이루어지지 않는다는 것입니다.
그 이유는 refCount가 atomic_int의 데이터 타입을 지니기 때문인데,
간단히 말해 스레드끼리의 데이터 경합이 일어나지 않는 데이터 타입임을 의미합니다.
이번 포스팅을 통해 shared_ptr에 대해 알아볼 수 있었습니다.
다음에는 나머지 스마트 포인터인 weak_ptr과 unique_ptr에 대해 알아보겠습니다.
'C++' 카테고리의 다른 글
자료구조 - 연결 리스트 (0) | 2024.08.18 |
---|---|
스마트 포인터 - weak_ptr, unique_ptr (0) | 2024.05.27 |
동적할당 (0) | 2024.04.29 |
iterator(반복자) (0) | 2024.04.29 |
오른값 참조 (0) | 2024.04.22 |