KoreanFoodie's Study
[C++ 게임 서버] 2-2. 스마트 포인터 본문
[C++ 게임 서버] 2-2. 스마트 포인터
핵심 :
1. 스마트 포인터에는 3종류가 있다. unique_ptr, shared_ptr, weak_ptr. 이 중, unique_ptr 는 소유권 개념을 위한 간단하고 가벼운 스마트 포인터이다.
2. shared_ptr 를 생성하면 사용하고자 하는 타입에 대한 메모리와 참조 카운트 등을 관리하는 제어 블록(Control Block)에 대한 메모리가 둘 다 할당된다. shared_ptr 의 경우 순환 문제가 발생할 수 있으므로, 주의해야 한다!
3. shared_ptr 에 대한 참조 횟수가 사라지면 우리가 사용하고자 하는 데이터에 대한 메모리는 해제되나, 만약 해당 포인터를 참조하는 weak_ptr 가 있을 경우, 제어 블록은 해당 포인터를 참조하는 weak_ptr 까지 전부 사라져야 메모리가 해제된다.
음.. 사실 스마트 포인터에 대한 얘기는 정말 지겹도록(?) 많이 해 왔으므로, 여기에서 더 추가할 내용은 거의 없기는 하다.
다만 위의 '핵심' 에 적힌 내용을 대략적으로 복습한다고 생각하고 넘어가자. 😅
우리가 평소에 매우 유용하게 사용하는 shared_ptr 의 경우, cycle 이 생겨서 메모리가 해제되지 않는 상황을 만들지 않도록 주의해야 한다. 예를 들어, 다음과 같은 상황이다.
class Parent
{
shared_ptr<Child> child;
}
class Child
{
shared_ptr<Parent> parent;
}
위처럼 클래스가 서로의 shared_ptr 객체를 들고 있을 경우, 자칫 메모리 해제가 안 될 수도 있다.
만약 서로가 서로를 어쩔 수 없이 참조해야 한다면.. 한쪽은 weak_ptr 를 들고 있도록 하자! 😉
class Parent
{
shared_ptr<Child> child;
}
class Child
{
weak_ptr<Parent> parent;
}
아, 그리고 shared_ptr 에 대한 참조 횟수가 사라지면 우리가 사용하고자 하는 데이터에 대한 메모리는 해제되나, 만약 해당 포인터를 참조하는 weak_ptr 가 있을 경우, 제어 블록은 해당 포인터를 참조하는 weak_ptr 까지 전부 사라져야 메모리가 해제된다.
진짜일까? 증거로, 소멸자 쪽 코드를 제시하겠다 😂
// shared_ptr 의 소멸자. _Decref() 를 호출한다
~shared_ptr() noexcept { // release resource
this->_Decref();
}
// _Decref() 는 use count 인 _Uses 를 체크한 후,
// _Destroy() 와 _Decwref() 를 호출한다
void _Decref() noexcept { // decrement use count
if (_MT_DECR(_Uses) == 0) {
_Destroy();
_Decwref();
}
}
// 그런데 _Delete_this() 가 호출되려면... Weak 카운트가 0 이어야 한다!
void _Decwref() noexcept { // decrement weak reference count
if (_MT_DECR(_Weaks) == 0) {
_Delete_this();
}
}
// 어라, 근데 _Destroy() 는 데이터만 해제한다.
// 제어블록까지 해제하려면 _Delete_this() 가 호출되어야 한다!
virtual void _Destroy() noexcept = 0; // destroy managed resource
virtual void _Delete_this() noexcept = 0; // destroy self
위의 코드를 보면, Weak Pointer 의 참조 횟수인 _Weaks 가 0 이어야 _Delete_this() 가 호출되어 제어블록이 해제 되는 것을 확인할 수 있다! 😊
그리고... weak_ptr 는 소멸할 때, _Decwref() 를 호출해 준다! 😮
~weak_ptr() noexcept {
this->_Decwref();
}
아, 스마트 포인터에 대해 이전에 정리해 둔 포스팅이 있으니, 더 많은 정보를 얻고 싶으면 이 글을 참고하자 😉
'Game Dev > Game Server' 카테고리의 다른 글
[C++ 게임 서버] 2-4. StompAllocator (0) | 2023.08.24 |
---|---|
[C++ 게임 서버] 2-3. Allocator (0) | 2023.08.23 |
[C++ 게임 서버] 2-1. Reference Counting (0) | 2023.08.21 |
[C++ 게임 서버] 1-24. 연습문제 (소수의 갯수 구하기) (0) | 2023.08.08 |
[C++ 게임 서버] 1-23. DeadLock 탐지 (0) | 2023.08.08 |
Comments