我想知道是否可行的C++标准库兼容allocator使用(固定大小)缓冲区,它存在于堆栈中.
不知怎的,似乎这个问题在SO上还没有被问过这个问题,尽管它可能已经在其他地方被暗示过了.
所以基本上,它似乎是,只要我去搜索,它应该能够创建一个使用固定大小的缓冲区的分配.现在,乍一看,这应该意味着它应该也有可能有一个使用固定大小的缓冲区,堆栈上的"生活"的分配,但它确实出现,这周围也没有普遍执行等.
让我举一个我的意思的例子:
{ ...
char buf[512];
typedef ...hmm?... local_allocator; // should use buf
typedef std::basic_string<char, std::char_traits<char>, local_allocator> lstring;
lstring str; // string object of max. 512 char
}
Run Code Online (Sandbox Code Playgroud)
这怎么可以实现?
这个问题的答案(感谢R. Martinho Fernandes)链接到来自铬源的基于堆栈的分配器:http://src.chromium.org/viewvc/chrome/trunk/src/base/stack_container.h
然而,这个类似乎非常特殊,特别是因为StackAllocator 它没有默认的ctor - 而且我认为每个分配器类都需要一个默认的ctor.
我一直在使用Howard Hinnant的堆栈分配器,它就像一个魅力,但实现的一些细节对我来说有点不清楚.
new和delete使用?的allocate()和deallocate()成员函数使用::operator new和::operator delete分别.同样,成员函数construct()使用全局布局new.为什么不允许任何用户定义的全局或类特定的重载?std::alignment_of<T>?max_size有throw()异常规范?这不是劝阻(参见例如更有效的C++第14项)?在分配器中发生异常时,是否真的有必要终止和中止?这是否随新的C++ 11 noexcept关键字而改变?construct()成员函数将是完美转发(在构造函数被调用)的理想选择.这是编写符合C++ 11标准的分配器的方法吗?c++ memory-alignment exception-specification allocator c++11
我最近遇到过Howard Hinnant的short_alloc,这是我见过的自定义分配器的最佳例子.
但是当我花费更多时间研究代码以将其集成到我的个人项目中时,我发现arena提供基于堆栈的分配的类可能并不总是返回正确对齐的内存.实际上,我担心只有第一次分配才能保证适当对齐(因为缓冲区本身具有强制对齐),请参阅下面的相关代码片段:
template <std::size_t N>
class arena
{
static const std::size_t alignment = 16;
alignas(alignment) char buf_[N];
char* ptr_;
//...
};
template <std::size_t N>
char*
arena<N>::allocate(std::size_t n)
{
assert(pointer_in_buffer(ptr_) && "short_alloc has outlived arena");
if (buf_ + N - ptr_ >= n)
{
char* r = ptr_;
ptr_ += n;
return r;
}
return static_cast<char*>(::operator new(n));
}
Run Code Online (Sandbox Code Playgroud)
我可以想出几种方法来解决这个问题(以一些内存浪费为代价),最简单的方法是size将allocate/deallocate函数四舍五入到多个alignment.
但在改变任何事情之前,我想确保我在这里没有遗漏一些东西......