I am trying to learn and write a self custom allocator - I was expecting that the cout statement should be printed but it never does - what is the wrong am I doing - how to write custom allocator:
#include <iostream>
#include <vector>
template < class T >
class MyAllocator : public std::allocator<T> {
public:
T* allocate(size_t size)
{
std::cout << "Allocation request size " << size << std::endl;
return new T[size];
}
};
int main()
{
std::vector <int, MyAllocator<int>> x;
x.push_back(10);
x.push_back(10);
x.push_back(10);
for (auto& var : x)
std::cout << "Value " << var << std::endl;
}
Output
Value 10
Value 10
Value 10
The inheritance of the standard allocator is not needed. Remove the inheritance : public std::allocator<T> and the compiler will be kind to inform you about what you missed to implement. Until C++17 the method construct must be implemented and it is used in std::vector, not allocate. Also value_type, deallocator and destroy are missing.
template< class U, class... Args >
void construct( U* p, Args&&... args );
Since you haven't implemented it and your allocator inherits the standard allocator, std::allocator::construct is called, that does not produce output.
The answer on this question is simple on the one hand and not simple in practice on the other hand.
std::allocator does not have a virtual destructor, so it should not be inherited, if it is not explicitly indicated like in std::enable_shared_from_this.Standard containers don't use class Allocator directly. They use std::allocator_traits. It helps to implement minimal user-defined allocators. If you implement only value_type, allocate and deallocate members of MyAllocator, std::allocator_traits<MyAllocator> makes MyAllocator fully conformed to C++ named requirements: Allocator.
MyAllocator carefully. It inherits std::allocator and "replaces" std::allocator::allocate (2).std::allocator_traits::allocate (2) reference manual, that is called by std::vector:
Calls
a.allocate(n, hint)if possible. If not possible (e.g. a has no two-argument member function allocate()), callsa.allocate(n).
What you have reached. You have implemented MyAllocator::allocate(std::size_t n) (2), but not MyAllocator::allocate(std::size_t n, const void* hint) (1), it is inherited from std::allocator. It is called from std::vector, that is not what you expected. If you had not inherited std::allocator, your implementation MyAllocator::allocate would be called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With