Why cast a char* to char** when allocating a buffer in the code sample below, and
what is happening here?
first_ = *reinterpret_cast<char **>(first_);
//CODE SAMPLE
public:
char * Allocate()
{
if (!first_)
return 0;
char *result = first_;
first_ = *reinterpret_cast<char **>(first_); // WHY?
--available_;
return result;
}
private:
char *buffers_;
char *first_;
std::size_t available_;
std::size_t maxnum_;
std::size_t buffersize_;
//WHOLE CLASS IS HERE
class Chunk
{
public:
Chunk(std::size_t buffersize, std::size_t buffernum)
: buffers_(0),
first_(0),
available_(0),
maxnum_(0),
buffersize_(0)
{
assert(buffersize > sizeof(char *) && buffernum > 0);
std::size_t len = buffersize * buffernum;
buffers_ = new char[len];
first_ = buffers_;
available_ = buffernum;
maxnum_ = buffernum;
buffersize_ = buffersize;
char *begin = buffers_;
char *end = buffers_ + len - buffersize_;
*reinterpret_cast<char **>(end) = 0;
for (; begin < end; begin += buffersize_)
{
char **next = reinterpret_cast<char **>(begin);
*next = begin + buffersize_;
}
}
~Chunk()
{
delete [] buffers_;
}
char * Allocate()
{
if (!first_)
return 0;
char *result = first_;
first_ = *reinterpret_cast<char **>(first_);
--available_;
return result;
}
void Deallocate(char *buffer)
{
*reinterpret_cast<char **>(buffer) = first_;
first_ = buffer;
++available_;
}
bool IsFull() const
{
return available_ == 0;
}
// the buffer is one of this chunk
bool IsChunkBuffer(char *buffer) const
{
assert(buffer);
return buffer >= buffers_ && buffer < buffers_ + maxnum_ * buffersize_;
}
private:
char *buffers_;
char *first_;
std::size_t available_;
std::size_t maxnum_;
std::size_t buffersize_;
};
It is a pool allocator. At the beginning of each free chunk, there is a pointer to the next free chunk. When the code above is executed,
first_points to a free chunk which is the first in a singly linked list of free chunks. Then it setsfirst_to the next free chunk and returns the previous one, which becomes allocated since it’s no longer in the list of free chunks.