开发者

C++ problem on casting

开发者 https://www.devze.com 2023-03-26 16:08 出处:网络
Why cast a char* to char** when allocating a buffer in the code sample below, and what is happening here?

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消