C++에서는 메모리 할당 및 해제에 표준 라이브러리에서 제공하는 new
및 delete
연산자를 사용합니다. 그러나 때로는 특정 요구 사항을 충족하기 위해 커스텀 메모리 할당 및 해제 동작을 구현해야 할 수도 있습니다. 이러한 요구 사항을 충족시키기 위해 C++은 할당자(allocator) 개념을 제공합니다. 할당자는 메모리 할당 및 해제 동작을 추상화하는 인터페이스를 제공하며, 이는 표준 라이브러리 컨테이너 및 사용자 정의 자료구조에서 사용됩니다.
할당자(allocator)의 개요
C++ 표준 라이브러리의 할당자는 std::allocator
라는 템플릿 클래스로 정의됩니다. 이는 allocate
, deallocate
등의 멤버 함수를 통해 메모리 할당 및 해제를 제어할 수 있습니다.
할당자를 사용하면 컨테이너의 메모리 할당 동작을 변경하거나 특정 메모리 영역에서만 할당을 수행할 수 있습니다. 또한, 커스텀 메모리 할당자를 사용하면 메모리 할당과 해제의 성능을 최적화할 수 있습니다.
커스텀 할당자(custom allocator)의 구현
커스텀 할당자를 구현하기 위해서는 크게 allocate
, deallocate
멤버 함수를 구현해야 합니다. 또한, 해당 할당자를 사용하는 컨테이너는 해당 할당자 타입을 인자로 받는 템플릿 형태로 구현해야 합니다.
다음은 간단한 커스텀 할당자의 예제입니다.
#include <iostream>
#include <memory>
template <class T>
struct MyCustomAllocator {
using value_type = T;
MyCustomAllocator() noexcept = default;
template <class U> MyCustomAllocator(const MyCustomAllocator<U>&) noexcept {}
T* allocate(std::size_t n) {
std::cout << "MyCustomAllocator: Allocating " << n * sizeof(T) << " bytes" << std::endl;
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void deallocate(T* p, std::size_t n) {
std::cout << "MyCustomAllocator: Deallocating " << n * sizeof(T) << " bytes" << std::endl;
::operator delete(p);
}
};
int main() {
std::vector<int, MyCustomAllocator<int>> vec;
vec.push_back(42);
}
위 예제에서는 MyCustomAllocator
라는 커스텀 할당자를 정의하고, std::vector
에서 이를 사용하는 방법을 보여줍니다.
마치며
커스텀 할당자를 사용하면 메모리 할당 및 해제 동작을 커스터마이징하고, 특정 요구 사항을 충족시킬 수 있습니다. 하지만, 실제로는 커스텀 할당자를 직접 구현하기보다는 표준 라이브러리에서 제공하는 기본 할당자를 효율적으로 활용하는 것이 좋습니다.
더 자세한 내용은 cppreference.com에서 확인할 수 있습니다.
참고 자료
위의 예제와 설명을 참고하여 커스텀 할당자에 대한 기본 동작 및 구현 방법에 대해 알아보았습니다.