【问题标题】:Circular buffer with pre-allocated buffer?带有预分配缓冲区的循环缓冲区?
【发布时间】:2013-09-26 11:36:37
【问题描述】:

是否有任何库具有可与预分配缓冲区一起使用的循环缓冲区类?我查看了 Boost::circular_buffer,但似乎它的所有构造函数都需要一个分配器。我不想重新发明循环缓冲区类,但必须使用预先分配的缓冲区。我想要类似的东西:

char buffer[1000];  // pre-allocated buffer.
circular_buffer_class cb; // a class that provides the interface as a circular buffer.
cb.attach(buffer, 1000); // attaching the preallocated buffer to the circular buffer class.
cb.do_something();

也许它可以通过一些特殊的分配器来实现?但是怎么做呢?

此外,我对其他类型的容器类感兴趣,例如固定大小的向量,可以与预分配缓冲区一起使用。

【问题讨论】:

  • 当你说“预分配缓冲区”时,它必须是你自己分配的,还是仅仅告诉容器在内部预分配自己的缓冲区就足够了?跨度>
  • 我是指我自己分配的那个。这是一款嵌入式系统软件。我得到了一个指向我被允许使用的内存区域的指针和大小。
  • 那么你最好写一个custom allocator 内部使用该内存区域的类。然后,您可以将该分配器与任何使用分配器的 STL/Boost 类一起使用。
  • 我想知道已经存在这样的自定义分配器。我的需要不应该如此罕见。我对分配器不是很熟悉,想找一个已经证明过的...
  • 你可以使用 boost c++。 boost.org/doc/libs/1_54_0/libs/circular_buffer/doc/…还有一个bounded_buffer例子

标签: c++ boost stl containers


【解决方案1】:

以下是一些与简单自定义分配器相关的链接,您可能会觉得有趣:

Hinnant's short_alloc and alignment guarantees

http://howardhinnant.github.io/stack_alloc.html

您可以使用此自定义分配器,它是衍生作品,可能非常接近您的意图:

#pragma once
#include <memory>
#include <cstddef>
#include <cassert>

/**
 * @class fixed_allocator
 * @see https://en.cppreference.com/w/cpp/memory/allocator
 *
 * @tparam The data type which is to be allocated.
 * The type is important for correct data alignment.
 */
template<typename data_type>
class fixed_allocator: public std::allocator<data_type>
{
public:
    using value_type = data_type;

    /**
     * @struct rebind is essential for this class to work properly.
     * It tells std::allocator to use our implementation of allocate and
     * deallocate rather than the default operator new, delete.
     */
    template <class other_type> struct rebind
    {
        using other = fixed_allocator<other_type>;
    };

    ~fixed_allocator()                                  = default;
    fixed_allocator()                                   = delete;    
    fixed_allocator(fixed_allocator const&)             = default;  // Required by rebind.
    fixed_allocator(fixed_allocator &&)                 = default;
    fixed_allocator& operator=(fixed_allocator const&)  = default;
    fixed_allocator& operator=(fixed_allocator&&)       = default;

    /**
     * Create a fixed allocator for the specified data_type.
     *
     * @param buffer The fixed backing store buffer to use for allocation.
     * @param length The number of data_type units held in the
     *               backing store allocation.
     */
    fixed_allocator(value_type *buffer, std::size_t length)
        : buffer_(buffer), buffer_length_(length), in_use_(false)
    {}

    /**
     * Allocates n * sizeof(value_type) bytes of uninitialized storage by
     * calling ::operator new(std::size_t) or
     * ::operator new(std::size_t, std::align_val_t) (since C++17).
     *
     * @param length       The number of value_type elements to allocate.
     *                     Must be <= this->buffer_length_.
     *
     * @return value_type* The allocate data block.
     * @note               For this fixed allocation this function must only
     *                     be called once before deallocate is called.
     *
     * @throw std::bad_alloc If the allocation fails.
     */
    value_type* allocate(std::size_t length)
    {
        assert(length <= this->buffer_length_);
        assert(not this->in_use_);
        this->in_use_ = true;
        return this->buffer_;
    }

    /**
     * Releases the fixed allocation block from use.
     * @param buffer The memory block being freed.
     *               Must be the same as this->buffer_.
     * @param length The number of bytes freed. Unchecked.
     */
    void deallocate(value_type *buffer, std::size_t length)
    {
        (void) length;
        assert(buffer == this->buffer_);
        assert(this->in_use_);
        this->in_use_ = false;
    }

private:
    value_type* buffer_;
    std::size_t buffer_length_;
    bool        in_use_;
};

您现在可以将此分配器的专用实例传递给 boost::circular_buffer 构造函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多