c++stlallocatorsgi

How does this allocator play the role of debugging?


When I read the source code of SGI/STL, I notice that

template <class _Alloc>
class debug_alloc {

private:

  enum {_S_extra = 8};  // Size of space used to store size.  Note
                        // that this must be large enough to preserve
                        // alignment.

public:

  static void* allocate(size_t __n)
  {
    char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra);
    *(size_t*)__result = __n;
    return __result + (int) _S_extra;
  }

  static void deallocate(void* __p, size_t __n)
  {
    char* __real_p = (char*)__p - (int) _S_extra;
    assert(*(size_t*)__real_p == __n);
    _Alloc::deallocate(__real_p, __n + (int) _S_extra);
  }

  static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz)
  {
    char* __real_p = (char*)__p - (int) _S_extra;
    assert(*(size_t*)__real_p == __old_sz);
    char* __result = (char*)
      _Alloc::reallocate(__real_p, __old_sz + (int) _S_extra,
                                   __new_sz + (int) _S_extra);
    *(size_t*)__result = __new_sz;
    return __result + (int) _S_extra;
  }

};

which is a debug template.

I can see that it assure that the allocated space is always larger than 8bytes, and I can also see that it replace the contents starting from the address of __result by using *(size_t*)__result = __n; but I am really confused about the purpose of this.

Why allocate the space then replace the contents with __n? Why then return __result + (int) _S_extra; and define char* __real_p = (char*)__p - (int) _S_extra;? Please explain in detail how function void* allocate(size_t __n) and void deallocate(void* __p, size_t __n) work on memory.

Link to source code: https://github.com/karottc/sgi-stl/blob/master/concept_checks.h


Solution

  • This allocator uses an 8-byte header in front of every allocation to record its size. It is common to store metadata like this next to the actual allocation. Even though the header contains a 4-byte int, 8 bytes ensure that the returned pointer is aligned to 8 bytes, a common requirement for larger types..

    As you can read from the code, allocate asks for n+8 bytes (call the resulting allocation p) , stores the size at the the beginning and returns p+8.

    Deallocate and reallocate are given the pointer p+8,so have to first subtract to get back to the real allocation.