我的问题基本上是跟进:
考虑到复制构造的要求,如何在C++ 11中编写有状态分配器?
基本上,尽管C++ 11标准现在允许有状态分配器,但我们仍然要求如果复制某个Allocator
,则副本必须通过==
运算符与原始值进行比较.这表明副本可以安全地释放由原始分配的内存,反之亦然.
因此,这样就可以禁止分配器维护独特的内部状态,例如slab-allocator或内存池等等.一种解决方案是使用shared_ptr
指针实现习惯用于内部状态,以便某些原始的所有副本Allocator
使用相同的底层内存池.那不算太糟糕.除了...
根据上面提到的问题,以及接受的答案,标准也似乎需要Allocator<T>
具有可互操作的拷贝构造函数Allocator<U>
,因此:
Allocator<T> alloc1;
Allocator<U> alloc2(alloc1);
assert(alloc1 == alloc2); // must hold true
Run Code Online (Sandbox Code Playgroud)
换句话说,无论模板参数如何,分配器类型都必须是可互操作的.这意味着如果我使用分配一些内存Allocator<T>
,我必须能够使用Allocator<U>
从原始构造的实例释放该内存Allocator<T>
.
...这对于任何尝试编写使用某种基于大小的内存池的分配器来说都是一个显示阻塞,就像simple_segregated_storage池只返回基于某个大小的块一样sizeof(T)
.
但是......这是真的吗?
我意识到需要可互操作的复制构造函数,Allocator<T>::rebind
因此容器的用户不需要知道say的内部细节,链接列表节点类型等.但据我所看到的,标准本身似乎并没有说什么,以便严厉作为一个要求Allocator<U>
构建从Allocator<T>
一定原文比较平等Allocator<T>
的实例.
该标准基本上需要以下语义,其中X是类型Allocator<T>
,a1和a2是X的实例,Y是类型Allocator<U>
,b是实例Allocator<U>
.
来自: …
我正在编写一个与std :: list一起使用的自定义分配器.列表大小将始终限制为一个较小的数字,列表元素将在约束树搜索算法中非常频繁地分配和释放,因此我认为自定义池分配器(从堆栈中分配元素)应该提高性能.
我的问题是std :: list如何分配用于存储链接/节点的数据结构.它将使用自定义分配器来分配元素,但如果节点仍然从堆中分配,那么这将不会有太大帮助.
这是我正在实现的自定义分配器:
#include <algorithm>
#include <cassert>
template <class Tp, std::size_t N>
class PoolStackAllocator {
public:
typedef Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
template<typename U>
struct rebind {
typedef PoolStackAllocator<U, N> other;
};
inline explicit PoolStackAllocator() : data_size_(0) {}
template <class U, std::size_t M>
inline explicit PoolStackAllocator(const PoolStackAllocator<U, M>& other) : data_size_(other.data_size_) {
typename PoolStackAllocator<U>::const_pointer i = other.data_;
typename PoolStackAllocator<U>::const_pointer …
Run Code Online (Sandbox Code Playgroud) 我正在编写一组分配器,目的是将它们用于非常高性能的环境中,因此需要一些限制使用(由编译器调节,而不是运行时错误)。我一直在阅读有状态分配器的 C++11 语义以及它们如何被符合容器使用。
我在下面粘贴了一个简单的分配器,它只包含分配器对象中的一块内存。在 C++03 中,这是非法的。
template <typename T, unsigned N>
class internal_allocator {
private:
unsigned char storage[N];
std::size_t cursor;
public:
typedef T value_type;
internal_allocator() : cursor(0) {}
~internal_allocator() { }
template <typename U>
internal_allocator(const internal_allocator<U>& other) {
// FIXME: What are the semantics here?
}
T* allocate(std::size_t n) {
T* ret = static_cast<T*>(&storage[cursor]);
cursor += n * sizeof(T);
if (cursor > N)
throw std::bad_alloc("Out of objects");
return ret;
}
void deallocate(T*, std::size_t) {
// Noop!
}
};
Run Code Online (Sandbox Code Playgroud)
在 C++11 …
我们有一个提供C接口的库extern "C"
,并且是从C代码中使用的,但是它内部使用STL容器和一些C++功能(如RAII)以方便使用.
现在有一个新的要求,即库应该能够指向来自客户端代码的自定义malloc
和free
函数,并将其用于内部的分配.我可以将它们放入库的上下文结构中,并在需要的地方使用它们,但是将它们与STL一起使用是令人费解的......
我查看了allocator类,但似乎STL容器必须能够使用默认构造函数来创建分配器,似乎没有办法将这些指针放入它们中,让它们通过它们调用来进行分配.
是否有可能以线程安全的方式(不使用全局变量)来解决这个问题?