简体   繁体   English

带有发布的 std::vector<> 的自定义分配器?

[英]Custom allocator for std::vector<> with release?

I am working with a 3rd party C API set in C++ that has two methods of concern for this discussion:我正在使用 C++ 中的第 3 方 C API 集,该 API 具有本次讨论所关注的两种方法:

  1. It's equivalent of malloc(): the_api_malloc(size) (plus a matching the_api_free())它相当于 malloc(): the_api_malloc(size) (加上一个匹配的 the_api_free())
  2. A function in which memory created with the_api_malloc() is returned to that takes ownership of it and the_api_free()'s it internally: the_api_give_back(ptr)一个函数,其中使用 the_api_malloc() 创建的内存返回给它,并在内部获取它的所有权和 the_api_free() 的所有权: the_api_give_back(ptr)

I have created a custom allocator wrapping the_api_malloc() and the_api_free() to use with for example std::vector.我创建了一个自定义分配器来包装 the_api_malloc() 和 the_api_free() 以用于例如 std::vector。 This works great.这很好用。

What I'd like to do is have a std::vector type class that utilizes my custom allocator but also has a release() method that when called, releases ownership of it's memory and therefor will not call my custom allocators the_api_free().我想要做的是有一个 std::vector 类型的类,它利用我的自定义分配器,但也有一个 release() 方法,当调用时,释放其内存的所有权,因此不会调用我的自定义分配器 the_api_free()。

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

Example usage:用法示例:

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

I'm not sure the best way to pull this off.我不确定解决这个问题的最佳方法。 What I have right now as a experiment is rather nasty:我现在的实验是相当讨厌的:

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;
    }
}

Is there a better way?有没有更好的办法?

UPDATE 1 : Here is what I've tried based on suggestions below.更新 1 :这是我根据下面的建议尝试过的。 This should also help illustrate desired behavior & where it is currently failing.这也应该有助于说明所需的行为以及当前失败的地方。

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

UPDATE 2: Tried creating a MyOwningAllocator and a MyNonOwningAllocator then swapping from the owning to the non-owning where at "release time", but can't get swap() to work as they are different types.更新 2:尝试创建一个 MyOwningAllocator 和一个 MyNonOwningAllocator,然后在“发布时间”从拥有位置切换到非拥有位置,但无法让 swap() 工作,因为它们是不同的类型。

Instead of trying to stop the vector from calling the allocator's free function, I'd include your release as a member of your allocator, and have it set a flag.我不会试图阻止向量调用分配器的自由函数,而是将您的release包含在分配器的成员中,并设置一个标志。 When the flag is set, the_api_free will simply return (ie, act as a nop).当标志被设置时, the_api_free将简单地返回(即,充当一个 nop)。

vector::swap will transfer ownership of the allocated block to another vector . vector::swap将分配块的所有权转移到另一个vector However, there is no way to stop a vector from calling vector::allocator_type::deallocate in its destructor, and there is no portable way to directly modify the internal pointers.但是,没有办法阻止向量在其析构函数中调用vector::allocator_type::deallocate ,也没有可移植的方法来直接修改内部指针。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 std :: vector中的自定义分配器 - Custom allocator in std::vector 带有自定义分配器的 std::vector 与 std::vector - std::vector against std::vector with custom allocator 模板typedef与std :: vector有自定义分配器 - template typedef with std::vector to have custom allocator 将忽略std :: vector <char>的自定义分配器 - Custom allocator for std::vector<char> is ignored 如何将带有自定义分配器的std :: vector传递给期望使用std :: allocator的函数? - How to pass an std::vector with custom allocator to a function that expects one with std::allocator? 具有自定义内存分配器的std :: vector的C ++模板 - c++ template for std::vector with custom memory allocator 我可以编写一个自定义分配器来确定std :: vector的重新分配量吗? - Can I write a custom allocator to decide the reallocation amount of std::vector? 使用自定义分配器分配器在std :: vector的末尾使用内存 - Utilize memory past the end of a std::vector using a custom overallocating allocator 使用自定义分配器分配std :: vector并在运行时键入unknown - Allocating a std::vector with custom allocator and type unknown at runtime static_assert 与带有自定义分配器的 std::vector 一起失败 - static_assert fails in conjunction with std::vector with a custom allocator
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM