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
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.