[C++] Allocator

seunghyun·2023년 4월 24일
1

Server

목록 보기
2/4

메모리 할당하는 것 자체는 결국 운영체제가 관리를 해주는 영역이므로, 경우에 따라 우리가 메모리를 요청하기 위해 계속해서 커널 레벨로 컨텍스트 스위칭을 하는 등의 형태로 동작할 수도 있다. 컨텍스트 스위칭은 비용이 큰 작업이므로, 이런 식으로 계속 스위칭을 하는 방법의 대안으로 나온 것이 메모리 풀링이다. 애초에 크게 할당받아서 유저 레벨에서 나눠서 쓰는 방법이다. 필수는 아니지만 한 번 살펴보자! 🏊🏻

new, delete 연산자도 오버로딩 대상이 될 수 있다. 아래는 예시이다!

static void* operator new(size_t size)
{
	cout << "new!" << size << endl;
    void* ptr = ::malloc(size);
    return ptr;
}

static void operator delete(void* ptr)
{
	cout << "delete!" << endl;
    ::free(ptr);
}

이렇게 커스텀으로 사용할 것이라면 전역으로 사용하는 대신 우리가 직접 지정해주는 편이 좋다.

placement new : 이미 할당된 메모리에서 객체의 생성자를 호출할 수 있다.

Type* memory = static_cast<Type*>(BaseAllocator::Alloc(sizeof(Type)));
// placement new
new(memory)Type();
return memory;

// Allocator.h
class Allocator
{
public:
	static void* ALloc(int32 size);
    static void Release(void* ptr);
};

// Allocator.cpp
void* BaseAllocator::Alloc(int32 size);
{
	return ::malloc(size);
}

void BaseAllocator::Release(void* ptr)
{
	::free(ptr);
}

int main()
{
	Knight* knight = xnew<Knight>();
    xdelete(knight);
}

// memory.h
#include "Allocator.h"
template<typename Type, typename... Args)
Type* xnew(Args&&... args)
{
	Type* memory = static_cast<Type*>(BaseAllocator::Alloc(sizeof(Type)));
	// placement new
	new(memory)Type();
	return memory;
}

template<typename Type>
void xdelete(Type* obj)
{
	
	BaseAllocator::Release(obj);
}

0개의 댓글