7

最近我一直在寻找一种池/分配器机制。Boost Pool 似乎提供了解决方案,但仍有一些东西无法从文档中推断出来。

需要分配什么

  1. 几个小班(〜30个字符)
  2. std::map (我想确保它不会自行执行动态分配器)
  3. pugi::xml 中的分配
  4. 标准::字符串

如何控制分配的地址空间(或只是数量)

object_pool 似乎提供了一种分配需求的好方法 1) 但是它想设置一个固定大小供分配器使用。默认情况下,它会自行获取内存。如果可能的话,我想给它可以在其中播放的地址空间。

char * mem_for_class[1024*1024];
boost::object_pool<my_class,mem_for_class> q;

或者:

const int max_no_objs=1024;
boost::object_pool<my_class,max_no_objs> q;

虽然 UserAllocator 在 Boost::Pool 中可用;它似乎打败了这一点。我担心所需的控制会使其效率太低……最好从头开始。

是否可以为 pool_allocator 设置一个固定区域?

这个问题和第一个有点相似。在将 boost::pool_allocator 提供给 std-type-class (例如 map) 时,boost pool 是否提供任何方式来限制分配内存的数量/位置

我的场景

嵌入式linux编程。系统必须永远运行下去。所以我们不能冒险进行任何内存分割。目前我主要是静态分配(堆栈),但也有一些原始的“新”。我想要一个分配方案,以确保每次程序循环时我都使用相同的内存区域。速度/空间很重要,但安全仍然是重中之重。

我希望 StackOverflow 是提问的地方。我尝试联系 Boost::Pool "Stephen" 的作者,但没有成功。我还没有找到任何特定于 Boost 的论坛。

4

1 回答 1

6

您始终可以创建与 STL 一起使用的分配器。如果它适用于 STL,它应该适用于 boost,因为您可以将 boost 分配器传递给 STL 容器。

考虑到上述情况,可以在指定的内存地址分配并且具有您指定的大小限制的分配器可以编写如下:

#include <iostream>
#include <vector>

template<typename T>
class CAllocator
{
    private:
        std::size_t size;
        T* data = nullptr;

    public:
        typedef T* pointer;
        typedef const T* const_pointer;

        typedef T& reference;
        typedef const T& const_reference;

        typedef std::size_t size_type;
        typedef std::ptrdiff_t difference_type;

        typedef T value_type;


        CAllocator() {}
        CAllocator(pointer data_ptr, size_type max_size) noexcept : size(max_size), data(data_ptr) {};

        template<typename U>
        CAllocator(const CAllocator<U>& other) noexcept {};

        CAllocator(const CAllocator &other) : size(other.size), data(other.data) {}

        template<typename U>
        struct rebind {typedef CAllocator<U> other;};

        pointer allocate(size_type n, const void* hint = 0) {return &data[0];}
        void deallocate(void* ptr, size_type n) {}
        size_type max_size() const {return size;}
};

template <typename T, typename U>
inline bool operator == (const CAllocator<T>&, const CAllocator<U>&) {return true;}

template <typename T, typename U>
inline bool operator != (const CAllocator<T>& a, const CAllocator<U>& b) {return !(a == b);}





int main()
{
    const int size = 1024 / 4;
    int ptr[size];
    std::vector<int, CAllocator<int>> vec(CAllocator<int>(&ptr[0], size));

    int ptr2[size];
    std::vector<int, CAllocator<int>> vec2(CAllocator<int>(&ptr2[0], size));

    vec.push_back(10);
    vec.push_back(20);
    vec2.push_back(30);
    vec2.push_back(40);


    for (std::size_t i = 0; i < vec2.size(); ++i)
    {
        int* val = &ptr2[i];
        std::cout<<*val<<"\n";
    }

    std::cout<<"\n\n";

    vec2 = vec;

    for (std::size_t i = 0; i < vec2.size(); ++i)
    {
        int* val = &ptr2[i];
        std::cout<<*val<<"\n";
    }

    std::cout<<"\n\n";
    vec2.clear();

    vec2.push_back(100);
    vec2.push_back(200);

    for (std::size_t i = 0; i < vec2.size(); ++i)
    {
        int* val = &ptr2[i];
        std::cout<<*val<<"\n";
    }
}

这个分配器确保所有内存都分配在指定的地址。无论是在堆栈上还是在堆上,都可以自由分配不超过您指定的数量。

您可以创建自己的池或使用 astd::unique_ptr作为单个容器的池。

编辑:对于字符串,您需要sizeof(_Rep_base). 请参阅:为什么 std::string 分配两次?

http://ideone.com/QWtxWg

它被定义为:

struct _Rep_base
{
    std::size_t     _M_length;
    std::size_t     _M_capacity;
    _Atomic_word        _M_refcount;
};

所以例子变成了:

struct Repbase
{
    std::size_t     length;
    std::size_t     capacity;
    std::int16_t    refcount;
};

int main()
{
    typedef std::basic_string<char, std::char_traits<char>, CAllocator<char>> CAString;

    const int size = 1024;
    char ptr[size] = {0};

    CAString str(CAllocator<char>(&ptr[0], size));
    str = "Hello";

    std::cout<<&ptr[sizeof(Repbase)];
}
于 2014-04-04T19:43:08.200 回答