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 sets first_
to the next free chunk and returns the previous one, which becomes allocated since it's no longer in the list of free chunks.
To complement @ybungalobill answer...
In C and C++ char
has two meaning: either as a true char
or as a "byte". I myself prefer to use unsigned char
to serve as a byte, and usually typedef it to something legible, but it is nonetheless something you ought to know.
Therefore, what you are seeing here is the manipulation of raw memory (typical in the case of an allocator), which appear under the form of an array of char
in buffers_ = new char[len];
.
The author will then take chunks of this array and use reinterpret_cast
to indicate to the compiler what he wants to store at this place in memory.
This is obviously low-level meddling (type unsafe) and not something you'd want to muddle with on a daily basis.
精彩评论