如何正确使用C++11风格的内存池



我正在尝试设计一个简单嵌入式应用程序的内部机制。数据块到达网络,需要传递到由寻址机制确定的组件。多个组件可以订阅同一地址。我想设计一种体系结构,将传入的块封装到从内存池分配的包装器对象中。只要需要,每个组件都可以保留包装器(以及包装器中的数据(,当所有组件都释放它时,它应该被释放。这时,它会返回到池中,并再次准备好进行分配。游泳池里的人精疲力竭并不令人担忧。

我计划使用这个满足Allocator的内存池实现。对于包装器对象的自动销毁,我计划使用std::shared_ptr,因此当所有组件释放包装器时,它会自动销毁,使用过的内存会返回到池中。

我不明白这两个概念是如何结合在一起的。如果我直接从池中分配内存(通过调用allocate()(,它会给我一个指向数据块的指针,这很好,但如何自动调用deallocate()?或者,我需要为我的包装器对象(如std::list(使用另一个容器,并将其传递给内存池分配器吗?

您可以将std::shared_ptr与使用std::allocate_shared的自定义分配器一起使用。这可能是您想要的,因为我假设您也希望使用池分配器来分配控制块(即引用计数(。

当使用std::allocate_shared构造对象时,分配器的副本存储在shared_ptr中,因此在销毁时将调用正确的deallocate()

请注意,您也可以使用自定义deleter创建std::shared_ptr,例如:

auto allocator = getAllocator<Foo>();
auto ptr = std::shared_ptr<Foo>(new(allocator.allocate()) Foo,
[&allocator](auto * ptr) { allocator.deallocate(ptr); });

然而,正如我所提到的,这可能不是您想要的,因为引用计数的空间不会使用分配器对象来分配。

顺便说一句,如果你还在"货比三家",这里有另一个我很喜欢的内存池实现:foonathan::memory。它提供自己的allocate_shared

最新更新