R P*_*ban 6 c++ boost allocator boost-pool c++11
我是新手,我想知道boost :: pool库如何帮助我创建自定义内存分配器.我有两个struct对象向量.第一个向量是结构类型A,而第二个向量是结构类型B.我如何重用分配给第一个向量的内存到第二个向量.
Boost Pool是一个定义一些分配器类型的库.
显然,图书馆的重点是提供Pool Allocators.
当您分配相同大小的对象时,池分配器会闪烁.
注意如果您的结构
A和结构B不相同/非常相似,您可能不喜欢这种设计假设.
框架提供的分配器使用单例池,它们区分容器value_type的大小.如果您想重用甚至在不同的值类型之间共享池,那就有点不灵活了.此外,单例池可能不灵活,并且意味着线程安全成本.
所以,我想知道是否可以掀起最简单的分配器来减轻这些问题.
我使用源代码boost::pool_alloc和cppreference示例作为灵感,然后进行了一些测试和内存分析.
这是我能想到的最简单的池分配器:
using Pool = boost::pool<boost::default_user_allocator_malloc_free>;
template <typename T> struct my_pool_alloc {
using value_type = T;
my_pool_alloc(Pool& pool) : _pool(pool) {
assert(pool_size() >= sizeof(T));
}
template <typename U>
my_pool_alloc(my_pool_alloc<U> const& other) : _pool(other._pool) {
assert(pool_size() >= sizeof(T));
}
T *allocate(const size_t n) {
T* ret = static_cast<T*>(_pool.ordered_malloc(n));
if (!ret && n) throw std::bad_alloc();
return ret;
}
void deallocate(T* ptr, const size_t n) {
if (ptr && n) _pool.ordered_free(ptr, n);
}
// for comparing
size_t pool_size() const { return _pool.get_requested_size(); }
private:
Pool& _pool;
};
template <class T, class U> bool operator==(const my_pool_alloc<T> &a, const my_pool_alloc<U> &b) { return a.pool_size()==b.pool_size(); }
template <class T, class U> bool operator!=(const my_pool_alloc<T> &a, const my_pool_alloc<U> &b) { return a.pool_size()!=b.pool_size(); }
Run Code Online (Sandbox Code Playgroud)
笔记:
在我的编译器上它适用于std::vector和Boost vector:
所有运行都是无泄漏的,并且ubsan/asan清洁.
注意我们如何重复使用具有不同结构大小的不同容器的相同池,以及我们如何一次使用多个活动容器,前提是元素类型符合请求大小(32)
struct A { char data[7]; };
struct B { char data[29]; };
int main() {
//using boost::container::vector;
using std::vector;
Pool pool(32); // 32 should fit both sizeof(A) and sizeof(B)
{
vector<A, my_pool_alloc<A> > v(1024, pool);
v.resize(20480);
};
// pool.release_memory();
{
vector<B, my_pool_alloc<B> > v(1024, pool);
v.resize(20480);
}
// pool.release_memory();
// sharing the pool between multiple live containers
{
vector<A, my_pool_alloc<A> > v(512, pool);
vector<B, my_pool_alloc<B> > w(512, pool);
v.resize(10240);
w.resize(10240);
};
}
Run Code Online (Sandbox Code Playgroud)
使用Valgrind的Memory Profiler显示,release_memory如下所示注释掉:
当评论中的release_memory()电话:
我希望这看起来像你想要的东西.
此分配器使用现有的pool委托回malloc/free来按需分配内存.要将它与固定的"领域"一起使用,您可能更喜欢simple_segregated_storage直接使用它.这篇文章看起来像一个很好的入门者https://theboostcpplibraries.com/boost.pool