2

我正在使用 C++ 中设置的第 3 方 C API,该讨论有两种关注方法:

  1. 它相当于 malloc():the_api_malloc(size)(加上匹配的 the_api_free())
  2. 使用 the_api_malloc() 创建的内存返回给该函数的函数,该函数在内部拥有它和 the_api_free() 的所有权:the_api_give_back(ptr)

我创建了一个自定义分配器,包装 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() 工作。

4

3 回答 3

1

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

于 2010-08-26T23:19:04.127 回答
1

我不会试图阻止向量调用分配器的自由函数,而是将你release作为分配器的成员包括在内,并让它设置一个标志。当设置标志时,the_api_free将简单地返回(即,充当 nop)。

于 2010-08-26T22:49:50.853 回答
1

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

于 2019-12-01T16:25:32.363 回答