I'm currently learning STL and I came across an example made by one of my teachers.
template <class T>
struct SpyAllocator : std::allocator<T>
{
typedef T value_type;
SpyAllocator(/*vector args*/) = default;
template<class U>
SpyAllocator(const SpyAllocator<U>& other){}
template<class U>
struct rebind
{
using other = SpyAllocator<U>;
};
T* allocate(std::size_t n)
{
T* p = (T*) new char[sizeof(T) * n];
memorySpy.NotifyAlloc(sizeof(T), n, p);
return p;
};
void deallocate(T* p, std::size_t n)
{
memorySpy.NotifyDealloc(p, n);
delete (char*)p;
}
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
};
template <class T, class U>
bool operator==(const SpyAllocator<T>&, const SpyAllocator<U>&) { return
false; }
template <class T, class U>
bool operator!=(const SpyAllocator<T>&, const SpyAllocator<U>&) { return
false; }
Above is his allocator implementation.
#define String std::basic_string<char, std::char_traits<char>, SpyAllocator<char>>
He defined std::basic_string
as String
.
In the main.cpp file,
int main()
{
DO(String s1 = "Bonjour");
DO(String s2 = " le monde !");
DO(String s3 = s1 + s2);
printf("s3 : %s\n", s3.c_str());
printf("\nDestroy vector\n\n");
return 0;
}
He is testing + operator and copy constructor and the result is
String s1 = "Bonjour"
String s2 = " le monde !"
String s3 = s1 + s2
*** Allocate block 1 : 31 elem of 1 bytes
s3 : Bonjour le monde !
Destroy vector
*** Deallocate block 1 : 31 elem of 1 bytes
my questions are:
1- I've counted the number of characters(including \0) of String s1
and String s2
, it's 19. But 31 is allocated. Allocate block 1 : 31 elem of 1 bytes
What is the reason behind this?
2- It seems like String s1
and String s2
constructors did not allocate any memory but String s1
and String s2
still have the value.
How is it possible?
Thank you for your time!
Here what we get when we look at the basic_string.h of the STDLib
enum
{
_S_local_capacity = 15 / sizeof(_CharT)
};
union
{
_CharT _M_local_buf[_S_local_capacity + 1];
size_type _M_allocated_capacity;
};
We know that std::string
is a typedef
for a specialization of a std::basic_string with char
type.
basic_string
contains a 15 bytes fixed buffer for short strings then we +1 for the \0
. So when we concatenate 2 strings which are stored into the small buffer, it will concatenate the whole then add +1 for the \0
. So it will be 15 + 15 + 1 = 31.
That's what I understood from the reading of basic_string.h