8 years ago, Stephen Lavavej published this blog post containing a simple allocator implementation, named the \"Mallocator\". Since then we\'ve transitioned to the era of C++11
STL himself has an answer to this question in his STL Features and Implementation techniques talk at CppCon 2014 (Starting at 26'30).
The slides are on github.
I merged the content of slides 28 and 29 below:
#include // size_t, malloc, free
#include // bad_alloc, bad_array_new_length
template struct Mallocator {
typedef T value_type;
Mallocator() noexcept { } // default ctor not required
template Mallocator(const Mallocator&) noexcept { }
template bool operator==(
const Mallocator&) const noexcept { return true; }
template bool operator!=(
const Mallocator&) const noexcept { return false; }
T * allocate(const size_t n) const {
if (n == 0) { return nullptr; }
if (n > static_cast(-1) / sizeof(T)) {
throw std::bad_array_new_length();
}
void * const pv = malloc(n * sizeof(T));
if (!pv) { throw std::bad_alloc(); }
return static_cast(pv);
}
void deallocate(T * const p, size_t) const noexcept {
free(p);
}
};
Note that it handles correctly the possible overflow in allocate.