C ++ проблема при кастинге - PullRequest
9 голосов
/ 07 августа 2011

Зачем приводить 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_;
    };

Ответы [ 2 ]

11 голосов
/ 07 августа 2011

Это распределитель пула. В начале каждого свободного чанка есть указатель на следующий свободный чанк. Когда приведенный выше код выполняется, first_ указывает на свободный фрагмент, который является первым в односвязном списке свободных фрагментов. Затем он устанавливает first_ для следующего свободного чанка и возвращает предыдущий, который становится выделенным, поскольку его больше нет в списке свободных чанков.

0 голосов
/ 07 августа 2011

В дополнение к @ybungalobill ответ ...

В C и C ++ char имеет два значения: либо как истинное char, либо как "байт".Я сам предпочитаю использовать unsigned char в качестве байта и обычно печатать его как что-то разборчивое, но, тем не менее, это то, что вы должны знать.

Поэтому то, что вы видите здесь, это манипулирование необработаннымпамять (типично для распределителя), которая отображается в виде массива char в buffers_ = new char[len]; .

. Затем автор возьмет куски этого массива и использует reinterpret_cast, чтобы указатькомпилятору то, что он хочет сохранить в этом месте в памяти.

Это, очевидно, низкоуровневое вмешательство (небезопасный тип), а не то, с чем вам бы хотелось ежедневно путаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...