3

I need a custom allocator for STL vectors and maps so it "allocates" memory in preallocated memory block. I came across this piece of code which is in almost every allocator out there.

    Allocator(const Allocator<U, growSize> &other)
    {
        if (!std::is_same<T, U>::value)
            rebindAllocator = new std::allocator<T>();
    }

Can somebody please explain what it does and why we need this interface to be implemented? Big thanks in advance.

Full source code

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 2
    "I came across this piece of code which is in almost every allocator out there." Do you have references? – Jeff Garrett Jan 07 '20 at 04:19
  • @JeffGarrett https://github.com/moya-lang/Allocator/blob/master/Allocator.h – Anton Stafeyev Jan 07 '20 at 10:45
  • @AntonStafeyev What you’ve posted/linked isn’t amazingly idiomatic C++ code, I wouldn’t use it as a reference. – Konrad Rudolph Jan 07 '20 at 11:12
  • @KonradRudolph i am still learning c++, so i dont really understand the whole concept of it to see which code is better and which is not. this why i am asking if some one could explain when does rebind occurs and how it is occuring – Anton Stafeyev Jan 07 '20 at 11:13
  • 2
    That’s fair. My point was simply that this isn’t typical code, and you *won’t* find it in “almost every allocator out there”. In fact, I’ve never seen similar logic, and, as far as I can tell, whoever implemented this code didn’t really understand C++ allocators either. – Konrad Rudolph Jan 07 '20 at 11:14
  • @KonradRudolph maybe you can point me to the better example so i can study that instead ? – Anton Stafeyev Jan 07 '20 at 11:15
  • Does this answer your question? [what does (template) rebind<> do?](https://stackoverflow.com/questions/14148756/what-does-template-rebind-do) – iliar Jan 07 '20 at 11:21
  • 2
    Honestly, I strongly advise against studying allocators until you are quite advanced with C++. They are *very* easy to get wrong, which is why their specification continues being rewritten in new C++ versions. Maybe [Howard Hinnant’s article](https://howardhinnant.github.io/allocator_boilerplate.html#new) has some insight. – Konrad Rudolph Jan 07 '20 at 11:24
  • @KonradRudolph it i slike absolutely a must in my project. because i dont want ot hammer actual allocator in a hot loop to avoid memory fragmentation on smaller devices – Anton Stafeyev Jan 07 '20 at 11:37
  • Have you **observed** problematic behaviour, or are you guessing that? – Caleth Jan 07 '20 at 14:49
  • Note that *isn't* a valid allocator, because it is neither *CopyConstructible* nor *MoveConstructible*. The `#ifdef _WIN32` sections are merely patching up places where Microsoft's implementation of `std::` is relying on those properties – Caleth Jan 07 '20 at 15:10
  • @Caleth yes indeed i observed it, since memory is very limited fragmentation causes malloc to return null while there is memory available but is fragmented so there is no place to fit in the block. so i decided to work on a better book keeping part of it with preallocated memory pool so i dont have to touch os stuff. – Anton Stafeyev Jan 07 '20 at 15:39

1 Answers1

1

Think of an allocator as a typed interface referencing some underlying untyped storage. Many allocators may reference the same storage.

Allocators are required to allow rebinding so that an allocator for T can be turned into an allocator for U referencing the same storage. Allocators are required to be copy constructible, and a copy of the allocator must reference the same storage. See cppreference.

This allocator implementation also is the storage. It derives from a memory pool. Therefore, it needs a way for a copied allocator to allocate and deallocate from the original storage, not its own. This is copyAllocator. For reasons which are not clear, it only does this on Windows.

Similarly, a rebound allocator needs to access the same storage. This allocator seems to violate that and use std::allocator. This means it is not fit for many STL use cases. std::map and other node-based containers will allocate with a rebound allocator, which means they won't use the memory pool.

Jeff Garrett
  • 5,863
  • 1
  • 13
  • 12