问题描述
我有一个程序,包含一个处理阶段,需要使用一堆不同的对象实例(所有分配在堆上)从一个多态类型的树,所有最终派生自一个共同的基类。
由于实例可能循环引用,没有明确的所有者,我想用 new
分配它们,原始指针,并将它们留在内存中的阶段(即使它们变得未引用),然后在使用这些实例的程序阶段后,我想一次删除所有这些。
我如何认为它的结构如下:
struct B; // common base class
vector< unique_ptr< B>> memory_pool;
struct B
{
B(){memory_pool.emplace_back(this); }
virtual〜B(){}
};
struct D:B {...}
int main()
{
...
/ / phase starts
D * p = new D(...);
...
//阶段结束
memory_pool.clear();
//所有B实例被删除,指针无效
...
}
除了小心所有的B实例被分配新的,并且没有人在内存池被清除后使用任何指针,这个实现有问题吗?
具体来说,我关心的是 this
指针用于构造一个 std :: unique_ptr
在基类构造函数中,在派生类构造函数完成之前。这是否会导致未定义的行为?如果是,是否有解决方法?
如果您还没有熟悉。从文档
内存管理是棘手的业务(线程,缓存,对齐,分段等)对于严重的生产代码,精心设计和仔细优化的库除非你的分析器显示瓶颈。
I have a program that contains a processing phase that needs to use a bunch of different object instances (all allocated on the heap) from a tree of polymorphic types, all eventually derived from a common base class.
As the instances may cyclically reference each other, and do not have a clear owner, I want allocated them with new
, handle them with raw pointers, and leave them in memory for the phase (even if they become unreferenced), and then after the phase of the program that uses these instances, I want to delete them all at once.
How I thought to structure it is as follows:
struct B; // common base class
vector<unique_ptr<B>> memory_pool;
struct B
{
B() { memory_pool.emplace_back(this); }
virtual ~B() {}
};
struct D : B { ... }
int main()
{
...
// phase begins
D* p = new D(...);
...
// phase ends
memory_pool.clear();
// all B instances are deleted, and pointers invalidated
...
}
Apart from being careful that all B instances are allocated with new, and that noone uses any pointers to them after the memory pool is cleared, are there problems with this implementation?
Specifically I am concerned about the fact that the this
pointer is used to construct a std::unique_ptr
in the base class constructor, before the derived class constructor has completed. Does this result in undefined behaviour? If so is there a workaround?
In case you haven't already, familiarize yourself with Boost.Pool. From the documentation
Memory management is tricky business (threading, caching, alignment, fragmentation, etc. etc.) For serious production code, well-designed and carefully optimized libraries are the way to go, unless your profiler demonstrates a bottleneck.
这篇关于C ++ 11内存池设计模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!