KoreanFoodie's Study

[C++ 게임 서버] 2-5. STL Allocator 본문

Game Dev/Game Server

[C++ 게임 서버] 2-5. STL Allocator

GoldGiver 2023. 8. 25. 16:13

Rookiss 님의 '[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버' 를 들으며 배운 내용을 정리하고 있습니다. 관심이 있으신 분은 꼭 한 번 들어보시기를 추천합니다!

[C++ 게임 서버] 2-5. STL Allocator

핵심 :

1. STL 자료구조에서 사용하는 allocator 대신, 우리가 직접 만든 STL Allocator 를 적용한 커스텀 STL 을 만들어 보자.

2. STL Allocator 는 allocate 와 deallocate 함수만 정의해 주면 되며, STL 특수화에서 Allocator 의 인자를 우리가 만든 STL Allocator 로 바꿔치기해주기만 하면 된다! 

우리는 지난 시간에 Stomp Allocator 를 구현하면서, 메모리 할당/해제를 커스터마이징 할 수 있다는 것을 알게 되었다.

그리고 한 발 더 나아가서, 사실 STL 자료구조(vector, queue 등)을 이용할 때도, 우리가 직접 만든 allocator 를 사용할 수 있다!

이전에 만든 Allocator 내지는 Stomp Allocator 의 기능을 그대로 활용한 STL Allocator 를 다음과 같이 정의할 것이다 :

/*-------------------
	STL Allocator
-------------------*/

template<typename T>
class StlAllocator
{
public:
	using value_type = T;

	StlAllocator() { }

	template<typename Other>
	StlAllocator(const StlAllocator<Other>&) { }

	T* allocate(size_t count)
	{
		const int32 size = static_cast<int32>(count * sizeof(T));
		return static_cast<T*>(Xalloc(size));
	}

	void deallocate(T* ptr, size_t count)
	{
		Xrelease(ptr);
	}
};

사실 핵심은, allocate 와 deallocate 함수를 제대로 정의하는 것이다.

allocate 를 보면, 인자로 들어가는 요소의 갯수 만큼에 value_type 을 곱한 만큼의 크기를 할당해 주는 것을 확인할 수 있다.

 

그리고 우리가 사용할 컨테이너를 모아둔 곳에 가서, STL Allocator 를 적용한 타입 특수화를 다음과 같이 정의한다 :

template<typename Type>
using Vector = vector<Type, StlAllocator<Type>>;

template<typename Type>
using List = list<Type, StlAllocator<Type>>;

template<typename Key, typename Type, typename Pred = less<Key>>
using Map = map<Key, Type, Pred, StlAllocator<pair<const Key, Type>>>;

template<typename Key, typename Pred = less<Key>>
using Set = set<Key, Pred, StlAllocator<Key>>;

template<typename Type>
using Deque = deque<Type, StlAllocator<Type>>;

template<typename Type, typename Container = Deque<Type>>
using Queue = queue<Type, Container>;

template<typename Type, typename Container = Deque<Type>>
using Stack = stack<Type, Container>;

template<typename Type, typename Container = Vector<Type>, typename Pred = less<typename Container::value_type>>
using PriorityQueue = priority_queue<Type, Container, Pred>;

using String = basic_string<char, char_traits<char>, StlAllocator<char>>;

using WString = basic_string<wchar_t, char_traits<wchar_t>, StlAllocator<wchar_t>>;

template<typename Key, typename Type, typename Hasher = hash<Key>, typename KeyEq = equal_to<Key>>
using HashMap = unordered_map<Key, Type, Hasher, KeyEq, StlAllocator<pair<const Key, Type>>>;

template<typename Key, typename Hasher = hash<Key>, typename KeyEq = equal_to<Key>>
using HashSet = unordered_set<Key, Hasher, KeyEq, StlAllocator<Key>>;

즉 기존 STL 의 특성을 그대로 사용하되, 원래 기본으로 잡혀있던 Allocator 대신 우리가 직접 만든 STL Allocator 를 사용하도록 인자를 바꿔치기해 주면 된다.

 

위처럼 정의했으면, 아래처럼 실제 STL 처럼 간단하게 사용하면 된다 😊 :

Vector<Knight> v(100);

Map<int32, Knight> m;
m[100] = Knight();
Comments