向量(容器)需要使用"allocator"吗?
Does a vector (container) need to use an "allocator"?
我正在研究如何创建自定义容器,例如eastl的容器和其他几个模型,我发现它们都使用了"分配器",就像std::vector
和std::allocator
一样。这让我思考,当向量容器的新实现通常具有new
和delete
的底层内存管理覆盖时,为什么要使用分配器?
对于小程序来说,能够在程序级别替换operator new()
和operator delete()
(及其数组版本)就足够了。如果你的程序由数百万行代码组成,运行许多不同的线程,这根本不合适。你经常想要甚至需要更好的控制。为了有效地使用自定义分配器,您还需要能够使用与外部分配器相同的对象来分配子对象。
例如,考虑在某种可能运行多个线程的服务器中回答请求时使用的内存竞技场。从operator new()
获取内存可能相当昂贵,因为它涉及到分配锁和在越来越碎片化的堆中找到合适的内存块。为了避免这种情况,您只需要分配几个内存块(理想情况下只分配一个,但您可能事先不知道所需的大小),并将所有对象都放在那里。分配器可以做到这一点。要做到这一点,您需要向所有分配内存的实体通知该内存块,也就是说,您需要将分配器传递给所有可能分配内存的对象。如果你分配了一个std::vector<std::string, A>
,那么std::string
对象应该知道分配器:仅仅告诉std::vector<std::string, A>
在哪里以及如何分配内存是不足以避免大多数内存分配的:你还需要告诉std::string
(好吧,实际上是std::basic_string<char, std::char_traits<char>, B>
,用于与A
相关的合适的分配器类型B
)。
也就是说,如果你真的想控制你的内存分配,你肯定想把分配器传给所有分配内存的东西。使用替换版本的全局内存管理工具可能会对您有所帮助,但这是相当有限的。如果您只想编写一个自定义容器,并且内存分配不是您关心的问题,那么您不一定需要麻烦。然而,在长时间运行的大型系统中,内存分配是众多问题之一。
分配器是定义标准库容器使用的内存模型的类。
每个标准库容器都有自己的默认分配器,但是容器的用户可以在默认分配器的基础上提供自己的分配器
这是为了增加灵活性
它确保用户可以提供自己的分配器,该分配器提供除常规堆之外的另一种形式的内存管理(例如:内存池)。
如果您想生成一个标准兼容的容器,那么答案当然是肯定的。。。分配器在标准中进行了描述,因此它们是必需的。
然而,根据我个人的经验,分配器并没有那么有用。。。因此,如果您正在开发一个特定用途的容器,以克服标准容器的一些结构限制,那么我建议您忘记分配器,除非您真的看到了使用它们的原因。
如果你开发一个容器只是因为你认为你可以比标准向量做得更好,那么我的猜测是你在浪费时间。我不喜欢分配器的想法设计(在类型上去掉一些不应该有的东西),但幸运的是,它们可以被忽略。当您不需要分配器(即总是)时,分配器唯一的烦恼可能是错误消息中的一些混乱。。不管怎样,那都是一团糟。
- 在提升multi_index容器中,是否定义了"default index"?
- 用于访问容器<T>数据成员的正确 API
- Eigen如何在容器循环中干净地附加矩阵
- 模板专用化(按容器):value_type
- 关联容器的下界复杂性:成员函数与非成员函数
- 更多constexpr容器是否需要mark_immutable_if_consexpr
- 在STL容器中使用模板类
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 检查函数返回类型是否与STL容器类型值相同
- STL算法函数在多个一维容器上的使用
- 如何将带有自定义对象的容器从C++传递到QML
- 在没有未定义行为的情况下实现类似std::vector的容器
- 将 BASE 派生类存储在同一容器中
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 在C++中迭代 2D 容器的最干净方法
- 将线程中的数据存储到全局容器的最佳方法?
- 向量(容器)需要使用"allocator"吗?
- 如果对象是可构造/可析构的,STL容器是否允许跳过调用allocator::construct和allocator::d
- 容器优化:为什么STL容器方法参数不再使用allocator::const_reference typedef
- STL容器库-在allocator类的不同实例上调用allocate/deallocate是否合法?