代码之家  ›  专栏  ›  技术社区  ›  Calmarius

是否可以编写一个自定义STL分配器,它使用指向用户提供的分配函数的指针?

  •  2
  • Calmarius  · 技术社区  · 11 年前

    我们有一个库,通过 extern "C" ,是从C代码中使用的,但为了方便,它内部使用了STL容器和一些C++特性,如RAII。

    现在有一个新的要求,即库应该能够获取指向自定义 malloc free 函数,并将其用于内部分配。我可以将它们放入库的上下文结构中,并在需要时使用它们,但将它们与STL一起使用是令人费解的。。。

    我查看了分配器类,但似乎STL容器必须能够使用默认构造函数来创建分配器,而且似乎没有办法将这些指针放置到它们中,让它们通过它们调用来执行分配。

    是否可以最好以线程安全的方式(不使用全局变量)解决此问题?

    3 回复  |  直到 11 年前
        1
  •  5
  •   Jonathan Wakely    11 年前

    我查看了分配器类,但似乎STL容器必须能够使用默认构造函数来创建分配器

    这不是真的,所有容器都可以用分配器显式构造,因此您可以创建分配器对象,然后将其传递给容器。

    extern "C"
    {
      typedef void* (*allocation_function)(size_t);
      typedef void (*deallocation_function)(void*);
    }
    
    template<typename T>
    class Allocator
    {
    public:
      typedef T value_type;
    
      Allocator(allocation_function alloc, deallocation_function dealloc)
      : m_allocate(alloc), m_deallocate(dealloc)
      { }
    
      template<typename U>
        Allocator(const Allocator<U>& a)
        : m_allocate(a.m_allocate), m_deallocate(a.m_deallocate)
        { }
    
      T* allocate(size_t n)
      { return static_cast<T*>(m_allocate(n * sizeof(T))); }
    
      void deallocate(T* p, size_t)
      { m_deallocate(p); }
    
    private:
      template<typename U>
        friend class Allocator<U>;
    
      template<typename U>
        friend bool operator==(const Allocator<U>&, const Allocator<U>&);
    
      allocation_function   m_allocate;
      deallocation_function m_deallocate;
    };
    
    template<typename T>
    bool operator==(const Allocator<T>& l, const Allocator<T>& r)
    { return l.m_allocate == r.m_allocate; }
    
    template<typename T>
    bool operator!=(const Allocator<T>& l, const Allocator<T>& r)
    { return !(l == r); }
    
    
    Allocator<int> a(custom_malloc, custom_free);
    std::vector<int, Allocator<int>> v(a);
    

    如果您使用的不是C++11,那么您需要为分配器提供更多的成员以满足旧的要求,但是上面的一个对于C++11来说是可以的。在C++03中使用自定义分配器是困难的,而且无论如何都不可移植,因此如果需要这样做,您应该使用C++11编译器。

        2
  •  0
  •   Community Mohan Dere    8 年前

    对例如,请查看 header gc/gc_allocator.h 从…起 Boehm garbage collector (您可以轻松地将较低的调用替换为 GC_MALLOC 由一些函数指针等)。看见 this answer .

        3
  •  -2
  •   randomusername    11 年前

    由于分配器不能是状态满的,但必须是默认可构造的,所以我建议在编译时使用模板来实例化分配器。