要求提升游泳池体验.作为具有预分配的分配器有用吗?

Ste*_*sen 6 c++ boost memory-management allocation objectpool

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

什么需要分配

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

如何控制地址空间以进行分配(或仅限金额)

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

char * mem_for_class[1024*1024];
boost::object_pool<my_class,mem_for_class> q;
Run Code Online (Sandbox Code Playgroud)

要么:

const int max_no_objs=1024;
boost::object_pool<my_class,max_no_objs> q;
Run Code Online (Sandbox Code Playgroud)

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

可以为pool_allocator设置固定区域吗?

问题有点类似于第一个问题.在将boost :: pool_allocator提供给std-type-class(例如map)时,boost pool是否提供了限制分配内存的位置的方法

我的情景

嵌入式linux编程.系统必须继续运行.所以我们不能冒任何内存分段的风险.目前我主要是静态分配(堆栈),还有一些原始的"新".我想要一个分配方案,确保每次程序循环时我使用相同的内存区域.速度/空间很重要,但安全仍然是首要任务.

我希望StackOverflow是值得一提的地方.我试图联系Boost :: Pool"Stephen"的作者,但没有运气.我还没有找到任何特定于Boost的论坛.

Bra*_*don 5

您始终可以创建一个与 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";
    }
}
Run Code Online (Sandbox Code Playgroud)

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

您可以创建自己的池或使用 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;
};
Run Code Online (Sandbox Code Playgroud)

所以例子变成了:

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)];
}
Run Code Online (Sandbox Code Playgroud)