C++ 需要增强池经验。它作为预分配的分配器有用吗?

C++ 需要增强池经验。它作为预分配的分配器有用吗?,c++,memory-management,boost,allocation,objectpool,C++,Memory Management,Boost,Allocation,Objectpool,最近我一直在寻找一种池/分配器机制。 boostpool似乎提供了解决方案,但仍然有一些东西是它无法从文档中推断出来的 需要分配什么 几个小班(~30个字符) std::map(我想确保它本身不执行动态分配器) pugi::xml中的分配 std::字符串 如何控制分配的地址空间(或只是数量) 对象池似乎为分配需求提供了一种很好的方法(1) 但是,它希望为分配器设置一个固定的大小。默认情况下,它会自动获取内存。 如果可能,我想给它的地址空间,它可以发挥内 char * mem_for_class

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

需要分配什么
  • 几个小班(~30个字符)
  • std::map(我想确保它本身不执行动态分配器)
  • pugi::xml中的分配
  • std::字符串
  • 如何控制分配的地址空间(或只是数量) 对象池似乎为分配需求提供了一种很好的方法(1) 但是,它希望为分配器设置一个固定的大小。默认情况下,它会自动获取内存。 如果可能,我想给它的地址空间,它可以发挥内

    char * mem_for_class[1024*1024];
    boost::object_pool<my_class,mem_for_class> q;
    
    类[1024*1024]的char*mem\u; boost::对象池q; 或:

    const int max_no_objs=1024;
    boost::对象池q;
    
    尽管UserAllocator在Boost::Pool中可用;这似乎有失偏颇。我担心需要的控制会使它效率太低。。。最好从零开始

    可以为池分配程序设置固定区域吗? 这个问题有点像第一个问题。 当将boost::pool_分配器提供给std类型的类(例如map)时,boost pool是否提供任何方式来限制分配的内存量/位置

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


    我希望StackOverflow是个好地方。我试图联系Boost::Pool“Stephen”的作者,但运气不好。我还没有找到任何特定于Boost的论坛。

    您可以创建一个与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";
        }
    }
    
    因此,这个例子变成:

    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)];
    }
    
    struct Repbase
    {
    标准:尺寸与长度;
    标准:尺寸和容量;
    std::int16_t参考计数;
    };
    int main()
    {
    typedef std::基本_字符串阉割;
    常量int size=1024;
    char ptr[size]={0};
    去势str(CAllocator(&ptr[0],size));
    str=“你好”;
    
    std::coutStrange,
    allocate…{return&data[0];}
    -这不总是返回相同的地址吗?是的。它总是返回相同的地址。但是,据我所知,所有STL容器都跟踪自己的内存,只有在需要更多内存时才调用“allocate”。否则它们调用“construct”来构造元素。试试看。虽然与boost::pool无关,谢谢!std::vector的好例子。我只做了短暂的尝试,但我可以通过调试器看到内存内容是如何变化的。顺便说一句:很抱歉响应太晚,答案在假期开始时就出现了。不过我仍然需要一些帮助(或自学)了解如何使用std::string(或者更确切地说,配置basic_string以使用此分配器)。请参见此处了解为什么需要字符串的偏移量:再次感谢您的快速调整!在您第一篇帖子之后,我尝试了类似的方法,但在模板的语法/参数方面存在问题。根据声明的RepBase结构,偏移量的使用似乎足够清楚。字符串仍然可以使用str类本身
    std::cout输出
    
    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)];
    }