C++ Custom Allocator | 'Custom Allocator' Guide
이 글의 핵심
template<typename T> class MyAllocator { public: using value_type = T; T allocate(size_t n) {.
What is Custom Allocator?
STL container memory management
template<typename T>
class MyAllocator {
public:
using value_type = T;
T* allocate(size_t n) {
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void deallocate(T* p, size_t n) {
::operator delete(p);
}
};
// Usage
std::vector<int, MyAllocator<int>> vec;
Basic Structure
template<typename T>
class Allocator {
public:
using value_type = T;
Allocator() = default;
template<typename U>
Allocator(const Allocator<U>&) {}
T* allocate(size_t n) {
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void deallocate(T* p, size_t n) {
::operator delete(p);
}
};
template<typename T, typename U>
bool operator==(const Allocator<T>&, const Allocator<U>&) {
return true;
}
template<typename T, typename U>
bool operator!=(const Allocator<T>&, const Allocator<U>&) {
return false;
}
Practical Examples
Example 1: Logging Allocator
template<typename T>
class LoggingAllocator {
public:
using value_type = T;
T* allocate(size_t n) {
std::cout << "Allocate: " << n << " * " << sizeof(T) << " bytes" << std::endl;
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void deallocate(T* p, size_t n) {
std::cout << "Deallocate: " << n << " * " << sizeof(T) << " bytes" << std::endl;
::operator delete(p);
}
};
int main() {
std::vector<int, LoggingAllocator<int>> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
}
Example 2: Pool Allocator
template<typename T>
class PoolAllocator {
MemoryPool* pool;
public:
using value_type = T;
PoolAllocator(MemoryPool* p) : pool(p) {}
template<typename U>
PoolAllocator(const PoolAllocator<U>& other) : pool(other.pool) {}
T* allocate(size_t n) {
if (n != 1) {
throw std::bad_alloc();
}
return static_cast<T*>(pool->allocate());
}
void deallocate(T* p, size_t n) {
pool->deallocate(p);
}
template<typename U>
friend class PoolAllocator;
};
int main() {
MemoryPool pool(sizeof(int), 100);
std::vector<int, PoolAllocator<int>> vec{&pool};
}
Example 3: Aligned Allocator
template<typename T, size_t Alignment = 64>
class AlignedAllocator {
public:
using value_type = T;
T* allocate(size_t n) {
void* ptr = aligned_alloc(Alignment, n * sizeof(T));
if (!ptr) {
throw std::bad_alloc();
}
return static_cast<T*>(ptr);
}
void deallocate(T* p, size_t n) {
free(p);
}
};
int main() {
// 64-byte alignment
std::vector<float, AlignedAllocator<float, 64>> vec;
}
Example 4: Statistics Allocator
template<typename T>
class StatsAllocator {
static inline size_t allocCount = 0;
static inline size_t deallocCount = 0;
static inline size_t bytesAllocated = 0;
public:
using value_type = T;
T* allocate(size_t n) {
++allocCount;
bytesAllocated += n * sizeof(T);
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void deallocate(T* p, size_t n) {
++deallocCount;
::operator delete(p);
}
static void printStats() {
std::cout << "Allocations: " << allocCount << std::endl;
std::cout << "Deallocations: " << deallocCount << std::endl;
std::cout << "Bytes: " << bytesAllocated << std::endl;
}
};
Allocator Requirements
template<typename T>
class Allocator {
public:
// Required
using value_type = T;
T* allocate(size_t n);
void deallocate(T* p, size_t n);
// Optional
template<typename U>
Allocator(const Allocator<U>&);
// Comparison
bool operator==(const Allocator&) const;
bool operator!=(const Allocator&) const;
};
Summary
Key Points
- Custom allocator: Customize STL container memory management
- Basic structure:
value_type,allocate(),deallocate() - Use cases: Logging, pool, alignment, statistics
- Requirements: Must implement required interface
When to Use
✅ Use custom allocator when:
- Need memory pool
- Need aligned allocation
- Need allocation tracking/profiling
- Need custom memory management
❌ Don’t use when:
- Default allocator is sufficient
- Adds unnecessary complexity
- Performance gain is negligible
Best Practices
- ✅ Implement required interface correctly
- ✅ Handle exceptions properly
- ✅ Consider allocator equality
- ❌ Don’t make allocators too complex
- ❌ Don’t forget thread safety if needed
Related Articles
Master custom allocators for efficient memory management! 🚀
Frequently Asked Questions (FAQ)
Q. When would I use this in practice?
A. Development blog post organizing C++ Custom Allocator.
Q. What should I read before this?
A. Follow the previous article or related articles links at the bottom of each post to learn in sequence. See the C++ series index for the full picture.
Q. Where can I study this more deeply?
A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.
Related Articles (Internal Links)
Other articles related to this topic.
Keywords Covered in This Article (Related Search Terms)
This article covers C++, allocator, memory, STL, custom.