C++ STL分配器与new操作符的比较

35
根据C++ Primer第四版第755页的注释:
现代C++程序通常应该使用allocator类来分配内存。这样更安全,更灵活。
我不太理解这个说法。到目前为止,我阅读的所有材料都教授使用new在C++中分配内存。书中展示了vector类如何利用allocator的示例。但是,我想不出其他情况。
有人可以帮助澄清这个说法吗?并给我更多的例子?何时应该使用allocator,何时使用new?谢谢!
2个回答

53
对于一般编程来说,是的,你应该使用newdelete。 然而,如果你正在编写一个库,那么就不应该这样做! 我没有你的教材,但我想它讨论的是在编写库代码的情况下分配器的使用。 库的用户可能希望控制从哪里精确地分配什么。如果库的所有分配都通过newdelete进行,用户将无法具有这种细粒度的控制。 所有STL容器都采用可选的分配器模板参数。容器将使用该分配器来满足其内部内存需求。默认情况下,如果省略分配器,它将使用std::allocator,该分配器使用newdelete(具体来说,是::operator new(size_t)::operator delete(void*))。 这样,该容器的用户就可以控制从哪里分配内存,如果他们需要的话。 实现与STL一起使用的自定义分配器的示例和说明:使用自定义池分配器提高性能 副注: STL的分配器方法在几个方面都非最优。我建议阅读迈向更好的分配器模型以讨论其中的一些问题。

2019年的修改: 自从此回答编写以来,C++的情况已经改善。C++11中支持状态分配器supported,在C++17中改进了这种支持。参与“Towards a Better Allocator Model”的一些人员参与了这些更改(例如:N2387),所以这很好(:


5
赞成“STL中关于内存分配器的方法并不是最优的”,同时附上“Towards a Better Allocator Model”链接。 - Paul Groke
1
你提供的链接非常有帮助! - Ivan Xiao

1

这两者并不矛盾。分配器是STL库容器适配器使用的PolicyPattern或StrategyPattern,用于为对象分配内存块。

这些分配器经常通过允许一次性分配元素范围,并使用放置new初始化来优化内存分配,也允许从二级、专用堆中选择项目,具体取决于块大小。

无论如何,最终结果几乎总是使用new(放置或默认)分配对象。


另一个生动的例子是例如boost库如何实现智能指针。由于智能指针非常小(开销很少),分配开销可能会成为负担。因此,实现一个专门的分配器来进行分配就有意义了,这样就可以拥有高效的std :: set < smartpointers >,std :: map < ...,smartpointer >等。
(现在我几乎确定boost实际上通过避免任何虚拟机实现了大多数智能指针的存储优化,因此vft,使类成为POD结构,并且只有原始指针作为存储;其中一些示例将不适用。但是,再推广到其他类型的智能指针(引用计数智能指针,成员函数指针,带实例引用的成员函数指针等)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接