[C++] STL Custom Allocator 사용
Custom Allocator를 사용해서 STL Container들이 사용할 버퍼를 공급할 수 있습니다.
STL Cotainer는 Element가 들어갈 Container Buffer의 할당시 템플릿으로 구현된 Allocator 클래스를 사용합니다.
STL에서의 할당 동작시의 힙 파편화가 우려되는 상황이라면,
커스텀된 Allocator 클래스를 우리가 직접 구현하고, 미리 구현해둔 메모리풀로 이어지게 해서
통제할 수 있습니다.
우선 STL Cotainer의 할당시 동작의 이해를 위해서 아주 간단한 allocator 클래스를 구현하겠습니다.
할당시 동작할 내부 구현을 바꿔서 프로젝트 상황에 맞게 사용하시면 되겠습니다.
물론 말씀드렸듯이 STL Cotainer는 템플릿을 통한 호출을 하기 때문에
함수의 시그니쳐(이름과 반환타입, 파라미터 타입)은 반드시 같아야 컴파일이 가능합니다.
template <class Type>
class CustomAllocatorForSTL
{
public:
typedef Type value_type;
Type* allocate(std::size_t numOfElement)
{
Type* Ret = new Type[numOfElement];
std::cout << "Buffer Address : \r\r\r" << Ret << " Allocated : " << numOfElement << " Elements. " << std::endl;
return Ret;
}
void deallocate(Type* Target, std::size_t numOfElement)
{
std::cout << "Old Buffer Address : \r\r\r" << Target <<" Deallocated : " << numOfElement << " Elements! " << std::endl;
delete[] Target;
}
void construct(Type* MintMemory, const Type& value)
{
//생성자만 호출.
//이전 메모리에서 복사할때 필요하다.
new ((void*)MintMemory) Type(value);
std::cout << "Copied Element Contents " << &value << " To " << MintMemory << std::endl;
}
void destroy(Type* Target)
{
Target->~Type();
}
CustomAllocatorForSTL(const CustomAllocatorForSTL& constlref) {}
CustomAllocatorForSTL() {}
template<class Type2>
class rebind
{
typedef CustomAllocatorForSTL<Type2> Other;
};
template<class Type2>
CustomAllocatorForSTL (const CustomAllocatorForSTL<Type2>& constlrefOther) {}
};
그리고 우선 간단하게 vector 컨테이너로 테스트를 해보겠습니다.
int main()
{
auto pVector = new std::vector<int, CustomAllocatorForSTL<int>>();
return 0;
}
원소를 넣어서 Initialize를 하지 않아도 vector 컨테이너 객체가 하나가 만들어지면, 딱 1개짜리 버퍼가 만들어집니다.
하지만 이것은 Container의 Element들을 위한 공간은 아닙니다.
이제 reserve를 해보겠습니다.
이 공간들이 Element들을 위한 Buffer입니다.
int main()
{
auto pVector = new std::vector<int, CustomAllocatorForSTL<int>>();
pVector->reserve(10);
pVector->reserve(30);
pVector->reserve(60);
return 0;
}
이제 느낌이 오실 것이라고 생각합니다.
재할당시 기존 버퍼를 없애버리고 새로운 버퍼로 교체를 합니다.
더 큰 집으로 이사를 간다고 보시면 됩니다.
물론 이사를 갈때 기존에 있던 것들은 다 들고 갑니다.
아래의 예시를 하나만 더 보겠습니다.
int main()
{
auto pVector = new std::vector<int, CustomAllocatorForSTL<int>>();
pVector->reserve(10);
//3개의 Element 삽입.
pVector->push_back(1);
pVector->push_back(2);
pVector->push_back(3);
//30개로 버퍼 크기를 늘린다.
pVector->reserve(30);
return 0;
}
더 큰 집을 사고 그 다음 기존 집에 있던걸 전부 옮깁니다.
int main()
{
auto pVector = new std::vector<int, CustomAllocatorForSTL<int>>();
for (int i = 0; i < 10; ++i)
pVector->push_back(1);
return 0;
}
reserve없이 push_back을 해도 동작원리는 같습니다.
int main()
{
auto pVector = new std::vector<int, CustomAllocatorForSTL<int>>();
for (int i = 0; i < 10; ++i)
pVector->push_back(1);
return 0;
}
int main()
{
auto pVector = new std::vector<int, CustomAllocatorForSTL<int>>;
auto pStack = new std::stack<int, std::deque<int, CustomAllocatorForSTL<int>>>;
auto pQueue = new std::queue<int, std::deque<int, CustomAllocatorForSTL<int>>>;
auto pList = new std::list<int, CustomAllocatorForSTL<int>>;
auto pHashMap = new std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, CustomAllocatorForSTL<int>>;
auto pHashSet = new std::unordered_set<int, std::hash<int>, std::equal_to<int>, CustomAllocatorForSTL<int>>;
return 0;
}
동작을 이해하셨으니 다양한 컨테이너에 대해 구현하신 Custom Allocator를 사용하시면 되겠습니다.
'C++' 카테고리의 다른 글
[C++] functor 만들기 (1) | 2025.06.04 |
---|---|
[C++] std::move 와 std::forward (0) | 2022.04.09 |
[C++] new[] , delete[] 오버로딩시 주의 사항. (0) | 2022.03.28 |
[C++] const lvalue reference, rvalue reference (2) | 2022.03.23 |
[C++] 스마트 포인터 unique_ptr, shared_ptr, weak_ptr (0) | 2022.03.19 |
댓글
이 글 공유하기
다른 글
-
[C++] functor 만들기
[C++] functor 만들기
2025.06.04 -
[C++] std::move 와 std::forward
[C++] std::move 와 std::forward
2022.04.09 -
[C++] new[] , delete[] 오버로딩시 주의 사항.
[C++] new[] , delete[] 오버로딩시 주의 사항.
2022.03.28 -
[C++] const lvalue reference, rvalue reference
[C++] const lvalue reference, rvalue reference
2022.03.23