[英]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 具有本次讨论所关注的两种方法:
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.