标签: allocator

令人信服的自定义C++分配器示例?

有什么理由放弃std::allocator支持自定义解决方案?您是否遇到过正确性,性能,可扩展性等绝对必要的情况?有什么非常聪明的例子吗?

自定义分配器一直是我不太需要的标准库的一个功能.我只是想知道SO上的任何人是否可以提供一些令人信服的例子来证明他们的存在.

c++ memory-management std memory-alignment allocator

166
推荐指数
13
解决办法
9万
查看次数

polymorphic_allocator:何时以及为什么要使用它?

是关于cppreference的文档,是工作草案.

我必须承认,我不明白什么是真正的目的,polymorphic_allocator何时/为什么/如何使用它.
例如,pmr::vector具有以下签名:

namespace pmr {
    template <class T>
    using vector = std::vector<T, polymorphic_allocator<T>>;
}
Run Code Online (Sandbox Code Playgroud)

什么是polymorphic_allocator要约?std::pmr::vector对老式的提供有什么好处std::vector?我现在能做什么才能做到现在为止?
分配器的真正目的是什么?我应该何时使用它?

c++ allocator c++17

87
推荐指数
3
解决办法
1万
查看次数

std :: vector*在增加容量时是否有*移动对象?或者,分配器可以"重新分配"吗?

一个不同的问题启发了以下思想:

在增加容量时是否std::vector<T> 必须移动所有元素?

据我所知,标准行为是底层分配器请求新大小的整个块,然后移动所有旧元素,然后销毁旧元素,然后解除分配旧内存.

在给定标准分配器接口的情况下,此行为似乎是唯一可能的正确解决方案.但我想知道,修改分配器以提供一个reallocate(std::size_t)可以返回a pair<pointer, bool>并可以映射到底层的函数是否有意义realloc()?这样做的好处是,如果操作系统实际上只能扩展分配的内存,那么根本不需要进行任何移动.布尔值表示内存是否已移动.

(std::realloc()也许不是最好的选择,因为如果我们不能扩展,我们不需要复制数据.所以实际上我们更想要类似的东西extend_or_malloc_new().编辑:也许is_pod基于特征的专业化将允许我们使用实际的realloc,包括它的按位副本.只是不一般.)

这似乎错过了机会.最坏的情况下,可以始终贯彻reallocate(size_t n)return make_pair(allocate(n), true);,所以不会有任何惩罚.

是否有任何问题导致此功能对C++不合适或不合适?

也许唯一可以利用这个的容器就是std::vector,但那时又是一个相当有用的容器.


更新:澄清一个小例子.目前resize():

pointer p = alloc.allocate(new_size);

for (size_t i = 0; i != old_size; ++i)
{
  alloc.construct(p + i, T(std::move(buf[i])))
  alloc.destroy(buf[i]);
}
for (size_t i = old_size; i < new_size; ++i)
{
  alloc.construct(p + i, T());
}

alloc.deallocate(buf); …
Run Code Online (Sandbox Code Playgroud)

c++ vector realloc allocator

51
推荐指数
2
解决办法
3107
查看次数

使std :: vector分配对齐的内存

是否可以使用std::vector自定义结构分配对齐的内存以便使用SIMD指令进行进一步处理?如果有可能,有Allocator没有人碰巧有这样的分配器,他可以分享?

c++ memory-management memory-alignment allocator

48
推荐指数
3
解决办法
2万
查看次数

为什么在c ++ 17中不推荐使用std :: allocator的构造和销毁函数?

c ++ 17规范不赞成使用对象constructdestroy成员std::allocator.用于弃用其他成员函数工作组提供的基本原理这里,标题下的"弃用的std ::分配器的所述冗余成员".

但是,他们没有具体提到为什么这两个成员被弃用或者建议取代该功能的原因.我假设暗示是用来std::allocator_traits::construct代替.

我有点困惑的construct是,在某些情况下实施是否仍然是必要的,尽管因为这个评论std::allocator_traits::construct

因为此函数提供自动回退到placement new,所以成员函数construct()是自C++ 11以来的可选Allocator要求.

对于自定义分配器(例如,对于页面对齐的内存使用memalign),回退到放置new总会产生正确的行为吗?

c++ memory-management allocator language-lawyer c++17

43
推荐指数
2
解决办法
4354
查看次数

矢量数据如何对齐?

如果我想std::vector用SSE 处理数据,我需要16字节对齐.我怎样才能做到这一点?我需要编写自己的分配器吗?或者默认分配器是否已经与16字节边界对齐?

c++ sse vector alignment allocator

40
推荐指数
3
解决办法
2万
查看次数

基于堆栈缓冲的STL分配器?

我想知道是否可行的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.

c++ stack stl allocator

37
推荐指数
3
解决办法
1万
查看次数

size_type可以大于std :: size_t吗?

标准容器,std::allocatorsize_type定义为std::size_t.但是,是否可以使用分配器来分配大小无法用size_t?表示的对象?换句话说,可以size_type永远大于size_t

c++ stl size-t allocator

36
推荐指数
4
解决办法
2341
查看次数

考虑到复制构造的要求,如何在C++ 11中编写有状态分配器?

据我所知,对于与STL容器一起使用的分配器的要求在C++ 11标准的第17.6.3.5节的表28中列出.

我对其中一些要求之间的相互作用感到有些困惑.给定一个类型X是类型分配器T,一类Y是"相应的allocator类"的类型U,实例a,a1a2X,和实例bY,表说:

  1. 表达式仅在分配的存储可以被解除分配时a1 == a2评估,反之亦然.truea1a2

  2. 表达式X a1(a);格式正确,不会通过异常退出,之后a1 == a也是如此.

  3. 表达式X a(b)格式正确,不会通过异常退出,然后退出a == b.

我读到这一点时说,所有分配器必须是可复制构造的,使得副本可以与原件互换.更糟糕的是,跨类型边界也是如此.这似乎是一个非常繁重的要求; 据我所知,它使大量类型的分配器变得不可能.

例如,假设我有一个我想在我的分配器中使用的freelist类,以便缓存释放的对象.除非我遗漏了某些东西,否则我无法在分配器中包含该类的实例,因为大小或对齐的TU可能不同,因此freelist条目不兼容.

我的问题:

  1. 我的解释是否正确?

  2. 我在一些地方读到C++ 11改进了对"有状态分配器"的支持.考虑到这些限制,情况如何?

  3. 你有什么建议可以做我想做的事吗?也就是说,如何在分配器中包含特定于分配类型的状态?

  4. 一般来说,分配器周围的语言似乎很草率.(例如,表28的序言假设它a是类型X&,但某些表达式重新定义a.)此外,至少GCC的支持是不符合的.分配器周围的这种奇怪的原因是什么?它只是一个不经常使用的功能吗?

c++ stl allocator c++11

34
推荐指数
3
解决办法
8913
查看次数

关于Hinnant的堆栈分配器的问题

我一直在使用Howard Hinnant的堆栈分配器,它就像一个魅力,但实现的一些细节对我来说有点不清楚.

  1. 为什么全球运营商newdelete使用?的allocate()deallocate()成员函数使用::operator new::operator delete分别.同样,成员函数construct()使用全局布局new.为什么不允许任何用户定义的全局或类特定的重载?
  2. 为什么对齐设置为硬编码16字节而不是std::alignment_of<T>
  3. 为什么构造函数和max_sizethrow()异常规范?这不是劝阻(参见例如更有效的C++第14项)?在分配器中发生异常时,是否真的有必要终止和中止?这是否随新的C++ 11 noexcept关键字而改变?
  4. construct()成员函数将是完美转发(在构造函数被调用)的理想选择.这是编写符合C++ 11标准的分配器的方法吗?
  5. 还需要进行哪些其他更改才能使当前代码C++ 11符合要求?

c++ memory-alignment exception-specification allocator c++11

32
推荐指数
1
解决办法
3149
查看次数