31

根据 C++ Primer 4th edition, page 755,有一条注释说:

现代 C++ 程序通常应该使用分配器类来分配内存。它更安全、更灵活。

我不太明白这个说法。到目前为止,我阅读的所有材料都教使用newC++ 分配内存。书中展示了向量类如何利用分配器的示例。但是,我想不出其他场景。

任何人都可以帮助澄清这一说法吗?并给我更多的例子?我应该何时使用分配器以及何时使用new?谢谢!

4

2 回答 2

48

对于一般编程,是的,您应该使用newand delete

但是,如果您正在编写库,则不应该!我没有你的教科书,但我想它是在编写库代码的上下文中讨论分配器。

图书馆的用户可能希望准确控制从哪里分配的内容。如果库的所有分配都通过newdelete,用户将无法获得如此细粒度的控制。

所有 STL 容器都采用可选的分配器模板参数。然后容器将使用该分配器来满足其内部内存需求。默认情况下,如果您省略分配器,它将使用std::allocator哪个使用newdelete(特别是::operator new(size_t)::operator delete(void*))。

这样,该容器的用户可以根据需要控制从何处分配内存。

实现与 STL 一起使用的自定义分配器的示例和说明:使用 STL的自定义池分配器提高性能

旁注:分配器的 STL 方法在几个方面都不是最佳的。我推荐阅读Towards a Better Allocator Model来讨论其中的一些问题。

2019 年编辑:自编写此答案以来,C++ 的情况有所改善。C++11支持有状态分配器,并且在 C++17 中改进了这种支持。参与“迈向更好的分配器模型”的一些人参与了这些更改(例如:N2387),这很好(:

于 2011-04-11T22:09:57.607 回答
1

两者并不矛盾。分配器是 STL 库的容器适配器用来分配内存块以供对象使用的 PolicyPattern 或 StrategyPattern。

这些分配器经常通过允许一次分配*范围的元素来优化内存分配,然后使用放置新的*项进行初始化,以根据块大小从辅助的、专门的堆中选择

一种或另一种方式,最终结果将(几乎总是)是用新的(放置或默认)分配对象


另一个生动的例子是 boost 库如何实现智能指针。因为智能指针非常小(开销很小),分配开销可能会成为负担。对于实现来说,定义一个专门的分配器来进行分配是有意义的,因此人们可能拥有高效的 std::set<> 智能指针、std::map<...、智能指针> 等。

(现在我几乎可以肯定,boost 实际上通过避免任何虚拟来优化大多数智能指针的存储,因此 vft,使类成为 POD 结构,只有原始指针作为存储;某些示例将不适用。但话又说回来,外推到其他类型的智能指针(引用智能指针、指向成员函数的指针、指向具有实例引用的成员函数的指针等))

于 2011-04-11T22:08:24.847 回答