向量(容器)是否需要使用“分配器”?

时间:2012-01-31 06:34:20

标签: c++ algorithm stl vector containers

我正在研究如何创建自定义容器,例如eastl的容器和其他几个模型,我发现它们都使用“分配器”,就像std::vectorstd::allocator一样。这让我想到,为什么矢量容器的新实现在使用分配器时通常会对newdelete进行底层内存管理覆盖?

3 个答案:

答案 0 :(得分:4)

能够在程序级替换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>适用于与B相关的合适分配器类型A

也就是说,如果您真的想要控制内存分配,那么您肯定希望将分配器传递给分配内存的所有内容。使用替换版本的全局内存管理工具可能对您有所帮助,但它受到相当大的限制。如果你只是想编写一个自定义容器并且内存分配不是你需要担心的话,你不一定需要打扰。然而,在运行很长一段时间的大型系统中,内存分配是众多问题之一。

答案 1 :(得分:1)

分配器是定义标准库容器使用的内存模型的类。

每个标准库容器都有自己的默认分配器,但容器的用户可以在默认情况下提供自己的分配器。
这是为了增加灵活性 它确保用户可以提供自己的分配器,它提供除常规堆之外的备用形式的内存管理(例如:内存池)。

答案 2 :(得分:0)

如果你想生产一个与标准兼容的容器,那么答案当然是肯定的......标准中描述了分配器,因此它们是必需的。

根据我的个人经验,分配器并不是那么有用......因此,如果您正在为特定用途开发容器以克服标准容器的某些结构限制,那么我建议忘记分配器,除非您真的看到了使用它们的原因。

如果您正在开发一个容器只是因为您认为自己可以做得比标准向量更好,那么我的猜测就是您在浪费时间。我不喜欢分配器的想法设计(放弃那些不应该存在的类型)但幸运的是它们可以被忽略。当你不需要分配器时(即总是),分配器的唯一烦恼可能是错误消息中的一些混乱......然而无论如何它都是一团糟。