简体   繁体   English

C++ STL 分配器与运算符 new

[英]C++ STL allocator vs operator new

According to C++ Primer 4th edition, page 755, there is a note saying:根据 C++ Primer 4th edition, page 755,有一个注释说:

Modern C++ programs ordinarily ought to use the allocator class to allocate memory.现代 C++ 程序通常应该使用分配器类来分配内存。 It is safer and more flexible.它更安全,更灵活。

I don't quite understand this statement.我不太明白这个说法。 So far all the materials I read teach using new to allocate memory in C++.到目前为止,我阅读的所有材料都使用new在 C++ 中分配内存。 An example of how vector class utilize allocator is shown in the book.书中展示了向量类如何使用分配器的示例。 However, I cannot think of other scenarios.但是,我想不出其他场景。

Can anyone help to clarify this statement?任何人都可以帮助澄清这个声明吗? and give me more examples?给我更多的例子? When should I use allocator and when to use new ?我什么时候应该使用分配器,什么时候使用new Thanks!谢谢!

For general programming, yes you should use new and delete .对于一般编程,是的,您应该使用newdelete

However, if you are writing a library, you should not!但是,如果您正在编写库,则不应该! I don't have your textbook, but I imagine it is discussing allocators in the context of writing library code.我没有你的教科书,但我想它是在编写库代码的上下文中讨论分配器的。

Users of a library may want control over exactly what gets allocated from where.库的用户可能希望准确控制从何处分配的内容。 If all of the library's allocations went through new and delete , the user would have no way to have that fine-grained level of control.如果库的所有分配都经过newdelete ,用户将无法进行细粒度的控制。

All STL containers take an optional allocator template argument.所有 STL 容器都采用可选的分配器模板参数。 The container will then use that allocator for its internal memory needs.然后容器将使用该分配器来满足其内部内存需求。 By default, if you omit the allocator, it will use std::allocator which uses new and delete (specifically, ::operator new(size_t) and ::operator delete(void*) ).默认情况下,如果省略分配器,它将使用使用newdelete std::allocator (特别是::operator new(size_t)::operator delete(void*) )。

This way, the user of that container can control where memory gets allocated from if they desire.这样,该容器的用户可以根据需要控制从何处分配内存。

Example of implementing a custom allocator for use with STL, and explanation: Improving Performance with Custom Pool Allocators for STL实现与 STL 一起使用的自定义分配器的示例,以及说明:使用 STL 的自定义池分配器提高性能

Side Note: The STL approach to allocators is non-optimal in several ways.旁注:分配器的 STL 方法在几个方面都不是最佳的。 I recommend reading Towards a Better Allocator Model for a discussion of some of those issues.我建议阅读Towards a Better Allocator Model来讨论其中的一些问题。

Edit in 2019: The situation in C++ has improved since this answer was written. 2019 年编辑:自从编写此答案以来,C++ 中的情况有所改善。 Stateful allocators are supported in C++11, and that support was improved in C++17. C++11 支持有状态分配器,并且在 C++17 中改进了这种支持。 Some of the people involved in the "Towards a Better Allocator Model" were involved in those changes (eg: N2387 ), so that's nice (:参与“迈向更好的分配器模型”的一些人参与了这些更改(例如: N2387 ),这很好(:

The two are not contradictory.两者并不矛盾。 Allocators are a PolicyPattern or StrategyPattern used by the STL libraries' container adapters to allocate chunks of memory for use with objects.分配器是 STL 库的容器适配器用来分配用于对象的内存块的 PolicyPattern 或 StrategyPattern。

These allocators frequently optimize memory allocation by allowing * ranges of elements to be allocated at once, and then initialized using a placement new * items to be selected from secondary, specialized heaps depending on blocksize这些分配器经常通过允许一次分配元素范围来优化内存分配,然后根据块大小使用从辅助、专用堆中选择的新项目进行初始化

One way or another, the end result will (almost always) be that the objects are allocated with new (placement or default)以一种或另一种方式,最终结果将(几乎总是)是使用新的(放置或默认)分配对象


Another vivid example would be how eg boost library implements smartpointers.另一个生动的例子是 boost 库如何实现智能指针。 Because smartpointers are very small (with little overhead) the allocation overhead might become a burden.由于智能指针非常小(开销很小),分配开销可能会成为负担。 It would make sense for the implementation to define a specialized allocator to do the allocations, so one may have efficient std::set<> of smartpointers, std::map<..., smartpointer> etc.实现定义一个专门的分配器来进行分配是有意义的,因此一个人可能拥有高效的 std::set<> 智能指针、std::map<...、smartpointer> 等。

(Now I'm almost sure that boost actually optimizes storage for most smartpointers by avoiding any virtuals, therefore the vft, making the class a POD structure, with only the raw pointer as storage; some of the example will not apply. But then again, extrapolate to other kinds of smartpointer (refcounting smartpointers, pointers to member functions, pointers to member functions with instance reference etc. etc.)) (现在我几乎可以肯定 boost 实际上通过避免任何虚拟对象来优化大多数智能指针的存储,因此 vft,使类成为 POD 结构,只有原始指针作为存储;一些示例将不适用。但话又说回来,外推到其他类型的智能指针(引用智能指针、指向成员函数的指针、指向具有实例引用的成员函数的指针等))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM