简体   繁体   English

STL自定义分配器来管理不同的内存空间

[英]STL custom allocators to manage different memory spaces

I would like to use different instances of an STL custom allocator class to manage different memory spaces, and then be able to specify an allocator instance to an STL container such that each container only draws from its assigned memory space. 我想使用STL自定义分配器类的不同实例来管理不同的内存空间,然后能够为STL容器指定一个分配器实例,这样每个容器只从其分配的内存空间中提取。 But I don't see how I can do that. 但我不明白我该怎么做。 I see how I can pass an allocator type into the template parameters of an STL container, but I want something akin to passing an allocator instance into the constructor of an STL container. 我看到如何将分配器类型传递给STL容器的模板参数,但我想要一些类似于将分配器实例传递到STL容器的构造函数中的东西。 Is there a way to do this in STL? 有没有办法在STL中这样做?

Unfortunately STL allocators cannot have state (or at least have to be very careful how that state is used) - each instance of a particular allocator type must be equivalent for STL containers to work effectively with them. 不幸的是,STL分配器不能具有状态(或者至少必须非常小心如何使用该状态) - 特定分配器类型的每个实例必须等效于STL容器才能有效地使用它们。 I don't recall the details right now, but I know that Scott Meyers discusses this problem at length in "Effective STL" , Item 10: Be aware of allocator conventions and restrictions. 我现在不记得细节,但我知道Scott Meyers在“Effective STL”中详细讨论了这个问题,第10项:注意分配器约定和限制。

However, you can have templated allocators that are very similar with the differences between the allocators being encapsulated in the allocator type and use different 'instantiations' of the allocator template (each template 'instantiation' is a different type). 但是,您可以使用与分配器类型中封装的分配器之间的差异非常相似的模板化分配器,并使用分配器模板的不同“实例化”(每个模板的“实例化”是不同的类型)。 Again, my recollection is that Meyers discusses this pretty clearly. 再一次,我的回忆是迈耶斯很清楚地讨论了这一点。

For example see this paragraph from an article by Anthony Aue, "Improving Performance with Custom Pool Allocators for STL" : 例如,请参阅Anthony Aue撰写的一篇文章“使用STL定制池分配器提高性能”

A potentially more serious caveat is that, since the allocator uses nonstatic data, it's not technically Standard compliant because the Standard requires that allocators of the same type be equivalent. 一个可能更严重的警告是,由于分配器使用非静态数据,因此技术上不符合标准,因为标准要求相同类型的分配器是等效的。 See Effective STL (Item 10) for a thorough explanation of the issue. 有关问题的详尽说明,请参阅有效STL(第10项)。 This amounts to requiring that an allocator for a given type be able to deallocate memory allocated by any other instance of an allocator for that type. 这相当于要求给定类型的分配器能够释放由该类型的分配器的任何其他实例分配的内存。 For many uses of standard containers, this requirement is unnecessary (some might say Draconian). 对于标准容器的许多用途,这个要求是不必要的(有些人可能会说Draconian)。 However, there are two cases where this requirement is absolutely necessary: list::splice and swap(). 但是,有两种情况需要这个要求:list :: splice和swap()。 The case of swap() is especially serious because it is needed in order to implement certain operations on containers in an exception-safe manner (see Exceptional C++, Item 12). swap()的情况特别严重,因为需要以异常安全的方式对容器实现某些操作(参见Exceptional C ++,Item 12)。 Technically, swap could be (and in some cases, is) implemented in the face of allocators that don't compare equally—items could be copied or the allocators could be swapped along with the data—but this is not always the case. 从技术上讲,交换可能(并且在某些情况下)是面对分配器而实现的,这些分配器不能同等地比较可以复制的项目,或者分配器可以与数据一起交换 - 但情况并非总是如此。 For this reason, if you're using swap() or list::splice, you should make sure to use HoldingPolicySingleton; 因此,如果您使用的是swap()或list :: splice,则应确保使用HoldingPolicySingleton; otherwise, you're bound to run into some really nasty behavior. 否则,你一定会遇到一些非常讨厌的行为。

See also Stephan T. Lavavej's discussion in this newsgroup thread . 另见Stephan T. Lavavej在这个新闻组主题中的讨论。

I'll update later tonight if someone else doesn't give the details in the meantime. 如果其他人在此期间没有提供详细信息,我今晚会更新。

The STL containers allow you to pass the allocator in as an argument to the constructor. STL容器允许您将分配器作为参数传递给构造函数。

For example here are the appropriate constructors for vector: 例如,这里是vector的适当构造函数:

explicit vector(const Allocator& = Allocator());
explicit vector(size_type n, const T& value = T(),
  const Allocator& = Allocator());
template <class InputIterator>
vector(InputIterator first, InputIterator last,
  const Allocator& = Allocator());

By default, they just use a default constructed allocator. 默认情况下,它们只使用默认构造的分配器。

Perhaps you could code a set of allocator types which contains a static pointing to seperate memory spaces. 也许您可以编写一组分配器类型,其中包含指向单独内存空间的静态。

Then, when the STL container constructs its allocator, the allocator uses the memory spaceassigned to that allocator. 然后,当STL容器构造其分配器时,分配器使用分配给该分配器的内存空间。

For simplicity, assume you want to use two memory spaces. 为简单起见,假设您要使用两个内存空间。 Create two allocator types, one for each space. 创建两个分配器类型,每个空间一个。 Pass the allocator type to the STL container constructors as required. 根据需要将分配器类型传递给STL容器构造函数。

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

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