std :: vector<>的自定义分配器与释放?

时间:2010-08-26 22:38:30

标签: c++ stl allocator

我正在使用C ++中的第三方C API集,该讨论涉及两种方法:

  1. 它相当于malloc(): the_api_malloc(size)(加上匹配的the_api_free())
  2. 一个函数,在该函数中,使用the_api_malloc()创建的内存将返回给它,并且内部的the_api_free()是 the_api_give_back(ptr)
  3. 我创建了一个自定义分配器,包含the_api_malloc()和the_api_free()以用于例如std :: vector。这很有效。

    我想要做的是有一个std :: vector类,它使用我的自定义分配器,但也有一个release()方法,在调用时,释放它的内存所有权,因此不会调用我的自定义分配器the_api_free ()。

    pointer release() /* pointer is of T* */
    

    使用示例:

    MyClass myClass(1024); // the_api_malloc()'s 1024 bytes
    // ... do something with myClass
    the_api_give_back(myClass.release());
    

    我不确定最好的解决方法。我现在所做的一个实验是相当讨厌的:

    class MyClass : public std::vector<char, MyAllocator<char> > {
    public:
        using typename std::vector<char, MyAllocator<char> >::pointer;
    
        pointer release() {
            // note: visual studio impl.
            pointer p = this->_Myfirst;
            this->_Myfirst = 0;
            this->_Mylast = 0;
            this->_Myend = 0;
            return p;
        }
    }
    

    有更好的方法吗?

    更新1 :以下是我根据以下建议尝试的内容。这也应该有助于说明所需的行为和它目前失败的地方。

    template <class T>
    class MyAllocator
    {
    public:
      // types omitted for clarity
    
      MyAllocator() : m_released(false) { }
    
      template <class U>
      MyAllocator(MyAllocator<U> const& a) : m_released(a.m_released) { }
    
      // other ctors, dtors, etc. omitted for clarity
    
      // note: allocate() utilizes the_api_malloc()
    
      void deallocate(pointer p, size_type num)
      {
        if(!m_released) {
          the_api_free(p);
        }
      }
    
      void release_ownership() { m_released = true; }
    
      bool m_released;
    };
    
    template <typename T>
    char* ReleaseOwernship(T& container)
    {
      container.get_allocator().release_ownership();
      return &container[0];
    }
    
    // usage:
    { // scope
      std::vector<char, MyAllocator<char> > vec;
    
      // ...do something to populate vec...
    
      char* p = ReleaseOwnership(vec);
      the_api_give_back(p); // this API takes ownership of p and will delete it itself
    } // end scope - note that MyAllocator::deallocate() gets called here -- m_release is still false
    

    更新2:尝试创建一个MyOwningAllocator和一个MyNonOwningAllocator,然后从拥有到“非发布时间”的非拥有者交换,但无法让swap()工作,因为它们是不同类型。

3 个答案:

答案 0 :(得分:1)

我没有尝试停止向量调用分配器的自由函数,而是将release作为分配器的成员包含在内,并让它设置一个标志。设置标志后,the_api_free将简单地返回(即充当nop)。

答案 1 :(得分:1)

vector::swap会将已分配区块的所有权转移给另一个vector。但是,没有办法阻止向量在其析构函数中调用vector::allocator_type::deallocate,并且没有可移植的方法来直接修改内部指针。

答案 2 :(得分:0)

我不知道您是否能够完成实现,但是我能够在其他SO answer中使用现代C ++为同一问题编写解决方案。