7

最近、プール/アロケータ メカニズムを探しています。Boost Pool は解決策を提供しているように見えますが、ドキュメントから推測できないことがまだあります。

何を割り当てる必要があるか

  1. いくつかの小さなクラス (~30 文字)
  2. std::map (動的アロケータを単独で実行しないようにしたい)
  3. pugi::xml 内の割り当て
  4. std::文字列

割り当て用のアドレス空間を制御する方法 (または単に量)

object_pool は、ニーズを割り当てるための良い方法を提供するように見えます 1) ただし、アロケーターが使用する固定サイズを設定したいと考えています。デフォルトでは、ifself でメモリを取得します。可能であれば、再生できるアドレス空間を指定したいと思います。

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 (マップなど) に指定するときに、割り当てられたメモリの量/場所を制限する方法を提供しますか?

私のシナリオ

組み込み Linux プログラミング。システムは永久に稼働し続けなければなりません。したがって、メモリのセグメンテーションを危険にさらすことはできません。現在、私は主に静的割り当て(スタック)だけでなく、生の「新しい」ものもいくつか使用しています。プログラムがループするたびに同じメモリ領域を使用する割り当てスキームが必要です。スピード・スペースも大事ですが、やはり安全が最優先。

StackOverflow が質問する場所であることを願っています。Boost::Pool の作者 "Stephen" に連絡を取ってみましたが、うまくいきませんでした。Boost 固有のフォーラムは見つかりませんでした。

4

1 に答える 1

6

STL で動作するアロケータはいつでも作成できます。STL で動作する場合は、ブースト アロケータを 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";
    }
}

このアロケータは、すべてのメモリが指定されたアドレスに割り当てられるようにします。スタック上にあるかヒープ上にあるかに関係なく、自由に割り当てることができますが、指定した量を超えることはありません。

独自のプールを作成するかstd::unique_ptr、単一のコンテナーのプールとして使用できます。

編集:文字列の場合、オフセットが必要ですsizeof(_Rep_base)。参照:なぜ std::string を 2 回割り当てるのですか?

および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 に答える