[c++] 커스텀 할당자(custom allocator)

C++에서는 메모리 할당 및 해제에 표준 라이브러리에서 제공하는 newdelete 연산자를 사용합니다. 그러나 때로는 특정 요구 사항을 충족하기 위해 커스텀 메모리 할당 및 해제 동작을 구현해야 할 수도 있습니다. 이러한 요구 사항을 충족시키기 위해 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에서 확인할 수 있습니다.

참고 자료

위의 예제와 설명을 참고하여 커스텀 할당자에 대한 기본 동작 및 구현 방법에 대해 알아보았습니다.