찬란

스마트 포인터(Smart pointer) 본문

프로그래밍 언어/C, C++

스마트 포인터(Smart pointer)

chan4 2023. 4. 13. 23:22

기존 포인터는 할당과 해제가 짝을 이루어야 하는 구조이다.

따라서 C 에서는 malloc 과 free를,

C++ 에서는 new 와 delete를 사용하여 메모리 할당과 해제를 관리하였다.

하지만 프로그램을 짜면서 이를 일관성 있게 모두 수행하는 것은 개발자의 피로도가 증가하고 생산성이

감소하는 복잡하고 피곤한 과정이다.

그래서 Java에서는 가비지 콜렉터(Garbage collector)라는 것이 존재하여 메모리 해제를 따로 관리하는데,

이는 결국 프로그램 사용량을 늘리는 일이기 때문에 작업이 좀 더 느리게 수행된다.

C++에서도 메모리 해제의 피로도를 줄여주기 위해 스마트 포인터라는 것을 지원하고 있다.(C++11이상부터!)

스마트 포인터의 종류에는 3가지가 있다.

unique pointer

shared pointer

weak pointer

기본적으로 모든 스마트 포인터는 각 포인터의 스코프(범위)가 지나면 자동으로 해제된다.

오히려 delete연산자를 사용하면 컴파일 에러가 발생한다.

또한 모든 스마트 포인터는 기본적으로 reset() 함수를 제공하는데,

해당 포인터가 가리키는 주소를 바꾸는 역할을 한다.

unique_ptr<int> ptr(new int(5));

ptr.reset(new int(6));

먼저 원래 ptr이 가리키고 있던 '5' 객체를 소멸시킨다.

그리고 ptr이 새로운 '6'객체를 가리키도록 한다.

 

 

unique_ptr (유일 포인터)

unique pointer는 말 그래도 유일한 주소 지정 소유권을 가지는 포인터이다.

std::unique_ptr<int> ptr1(new int(5));

unique_ptr은 유일한 포인터기 때문에 다른 포인터가 같은 주소를 가리킬 수 없다.

예를 들면,

std::unique_ptr<int> ptr2 = ptr1; // compile error

이런 식으로 ptr1이 가리키는 주소를 ptr2도 가리켜 버리면 컴파일 에러가 발생한다.

(얕은 복사가 불가능하다는 뜻이다)

소유권을 이전하고 싶으면 release()함수를 사용하면 된다.

std::unique_ptr<int> ptr2(ptr1.release());

이렇게 하면 ptr1은 가리키고 있던 주소(객체)는 소멸되고, ptr2가 원래 ptr1이 가리키던 주소를 가리키게 된다.


shared_ptr (공유 포인터)

한 주소를 여러 포인터가 가리킬 수 있다.

std::shared_ptr<int> ptr1(new int(5));

std::shared_ptr<int> ptr2 = ptr1; // 복사 생성 가능

shared_ptr은 use_count라는 변수를 관리함

* use_count: 해당 객체를 몇 개의 포인터가 가리키는가 (= 소유권을 몇 개의 포인터가 가지고 있는가)

공유된 포인터들은 스코프가 끝나도 소멸(해제)되지 않는다!

use_count 가 0이 되면, (= 해당 객체를 가리키는 포인터가 없어지면) 그 때 소멸(해제)시킨다.

 

weak_ptr (약한 포인터)

소유권을 가지지 않는 포인터.

그저 가리키키만 하는 포인터

보통 shared_ptr과 같이 사용

std::shared_ptr<int> ptr1(new int(5));

std::weak_ptr<int> ptr2 = ptr1; // ptr1의 use_count는 여전히 1임!

weak_ptr는 역참조하여 직접 접근할 수 없음!!

if(!ptr2.expired()){

std::cout << ptr2.lock()->getX() << std::endl;

expired() : 해당 포인터가 가리키는 객체가 아직 살아 있는지 판별

lock() : 객체가 살아 있으면 해당 포인터가 가리키는 객체를 가리키는 공유 포인터를 반환

'프로그래밍 언어 > C, C++' 카테고리의 다른 글

포인터와 배열 (Pointer and Array)  (0) 2023.04.13
포인터와 const  (0) 2023.04.13
이중 포인터 (Pointers to pointers)  (0) 2023.04.13
exit() 함수  (0) 2023.04.13
[C/C++] 파일 입출력 - 스트림  (1) 2023.04.13
Comments