[C++] 자원 관리와 스마트 포인터
모든 프로그래밍 언어에서 동적할당된 자원의 관리는 늘 걱정거리였고, 지금도 그렇다.
일반적으로 함수에서 선언되는 그냥 '지역 변수' 등에는 별다른 메모리 문제가 없다. 당연하다. 함수나 영역(scope)이 종료되면 다 죽으니까!
(재귀로 인한 오버플로 제외)
그런데 동적할당된 값은 함수 영역에 종속되지 않으며, 그 할당 해제의 시점을 관리하기가 매우 어렵다.
C/C++이나 기타 과거의 언어들에선, 해제를 직접 손으로 해줘야만 했다. 해제를 하는걸 까먹는다면 메모리가 할당된 채로 계속 남아있는 메모리 누수(leak)가 발생한다.

이걸 막으려면 꼬박꼬박 해제를 해줘야한다.
이런 식으로 말이다.

할당해제를 바로바로 해주는 버릇을 들이면 괜찮긴 한데... 정신없이 작성하다보면 빼먹을 경우도 반드시 발생할 것이다.
그리고 위에서는 그나마 생성한 함수의 끝에서 할당해제를 바로 했지만, 영역을 넘나들다가 해제를 해야할 상황도 충분히 존재한다.

코드를 다 단순화해놔서 그렇게 와닿지 않을 수도 있다. 하지만 코드가 조금만 더 커지고 복잡해져도 실수로 인한 메모리 누수(leak)가 온갖 군데에서 발생할 것이다.
참 머리아픈 일이다.
그래서 자바, 씨샵, 파이썬 등의 고오급 언어들에선 이에 대한 해결책으로 런타임에 가비지 컬렉터(GC)라는 걸 달아버렸다. 가비지 컬렉터는 동적할당된 데이터를 추적, 적절한 때에 할당해제하도록 해서 메모리 누수를 방지한다.
근데 문제는 저게... 성능을 많이 잡아먹는다는 것이다. 수시로 추적을 해야 하는 것도 비용이고, 자원을 모아서 정리하기 때문에 freezing이라는 버벅거림 부작용도 존재한다.
게다가 별도의 런타임도 필요하다.
성능에 미치고 환장하는 C++에선 절대 납득할 수가 없는 방식이다.
하지만 C++은 마침내 성능을 유지하며 자원 관리를 자동으로 해줄 방식을 고안해냈으니, 그게 바로 스마트 포인터(Smart Pointer:똑똑한 포인터)다.
별개의 런타임이 필요했던 가비지 컬렉트와 달리, 스마트포인터는 단순한 프로그램 코드를 통해 자원의 생명주기를 제어한다.
C++의 스마트포인터는 C++11부터 정식으로 지원되며,
unique_ptr, shared_ptr 총 두가지가 존재한다.
unique_ptr은 사용이 까다롭지만 부작용이 적으며, 성능이 아주 좋다.
shared_ptr은 사용이 편하지만 근본적인 결함이 존재하며 성능에 약간의 부하가 있다.
이에 대한 자세한 설명은 이후 포스트에서 따로 다룬다.
unique_ptr: https://m.blog.naver.com/sssang97/221805546474
shared_ptr: https://m.blog.naver.com/sssang97/221805985226
예전에 unique_ptr의 전신으로 auto_ptr이란 녀석도 있었는데. 결함덩어리라서 삭제됐다. 몰라도 된다.
C++11을 사용할 수 없는 상황이라도 괜찮다. boost 라이브러리에 그를 위한 스마트 포인터들이 정의되어있다. 그걸 써도 된다.