为什么在下面的代码示例中分配缓冲区时将char *转换为char **,和 这里发生了什么?
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_;
};
答案 0 :(得分:11)
它是一个池分配器。在每个空闲块的开头,有一个指向下一个空闲块的指针。当执行上面的代码时,first_
指向一个空闲块,这是单个链接的空闲块列表中的第一个。然后它将first_
设置为下一个空闲块并返回前一个空闲块,由于它不再位于空闲块列表中,因此会被分配。
答案 1 :(得分:0)
补充@ybungalobill回答...
在C和C ++中char
有两个含义:要么是真char
,要么是“字节”。我自己更喜欢使用unsigned char
作为一个字节,并且通常将其定义为易读的东西,但它仍然是您应该知道的。
因此,你在这里看到的是原始内存的操作(在分配器的情况下是典型的),它以char
中的buffers_ = new char[len];
数组的形式出现。
然后,作者将获取此数组的块并使用reinterpret_cast
向编译器指示他想要在内存中存储的内容。
这显然是低级干预(类型不安全),而不是你每天都想要混淆的东西。