서버/메모리 관리

2. 스마트포인터

광란의슈가슈가룬 2024. 8. 11. 03:21

스마트포인터는 동적 메모리를 관리하는 클래스이다. 일반적인 포인터와 똑같이 사용할 수 있지만 프로그래머가 직접 메모리 해제를 해주어야하는 포인터와 달리 스마트포인터는 알아서 메모리를 해제해준다.

 

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

 

1) unique_ptr

unique_ptr<int> ptr1 = make_unique<int>(10);
unique_ptr<int> ptr2(new int(10));

unique_ptr은 위와 같이 사용할 수 있고 unique라는 단어 뜻 그대로 다른 포인터가 해당 객체를 가르킬 수 없다. 그래서 복사도 불가능하다. 따라서 move와 같은 함수를 사용하여 객체의 소유권을 완전히 넘겨주는 식으로만 동작한다.

 

2) shared_ptr

shared_ptr<int> ptr1 = make_shared<int>(10);
shared_ptr<int> ptr2(new int(10));

shared_ptr도 unique_ptr와 같은 방식으로 사용 가능하다. 전 게시글의 직접 구현한 Shared Pointer은 이미 만들어져 있는 클래스에 대해서는 사용할 수 없었지만 이는 기존의 클래스에 대해서도 사용 가능하다. shared_ptr은 직접 구현도 해보았는데 참조하는 수를 카운트해서 아무도 참조하지 않을 때 소멸시킨다. 위 코드에서 2번째와 같이 new로 만들 경우 [T*] [RefCountBlock*] 이런식으로 2번 메모리를 할당하게 된다. 하지만 make_shared로 만들 경우 [T*  |   RefCountBlock*] 이렇게 한번에 메모리를 할당하므로 조금 더 효율적인 방식이라고 할 수 있다.

 

3) weak_ptr

shared_ptr<int> ptr1 = make_shared<int>(10);

weak_ptr<int> ptr2 = ptr1;

weak_ptr은 shared_ptr을 받아서 사용한다. weak_ptr은 그냥 사용할 수 없고

bool expired = ptr2.expired();

ptr1을 받았기 때문에 expired라는 함수를 사용하여 ptr1이 가르키고 있는 객체가 존재하고 있는지 확인을 먼저 한 후 사용해야 한다.

shared_ptr<int> ptr3 = ptr2.lock();

또는 이처럼 다시 shared_ptr로 캐스팅을 한 후 사용해야 한다. 만약 객체가 소멸되었다면 ptr3는 nullptr이 된다.

 

weak_ptr은 shared_ptr이 참조하고 있는 객체를 똑같이 가르키긴 하지만 shared_ptr의 RefCount는 증가하지 않는다. 그렇기 때문에 해당 객체의 수명 주기에 영향을 주지 않는다. 따라서 순환 문제가 발생하더라도 한 객체를 weak_ptr로 가지고 있으면 간단하게 문제를 해결할 수 있다.

'서버 > 메모리 관리' 카테고리의 다른 글

6. Memory Pool #1  (0) 2024.08.20
5. STL Allocator  (0) 2024.08.16
4. Stomp Allocator  (0) 2024.08.16
3. Allocator  (0) 2024.08.11
1. Reference Counting  (0) 2024.08.09