【发布时间】:2018-07-06 02:32:44
【问题描述】:
我有一个场景,我有以下方式表示的多个操作:
struct Op {
virtual void Run() = 0;
};
struct FooOp : public Op {
const std::vector<char> v;
const std::string s;
FooOp(const std::vector<char> &v, const std::string &s) : v(v), s(s) {}
void Run() { std::cout << "FooOp::Run" << '\n'; }
};
// (...)
我的应用程序在多个通道中工作。在每一次传递中,我都想创建许多这样的操作,并且在传递结束时我可以同时丢弃它们。所以我想为这些操作预分配一些内存块,并从这个内存中分配新的操作。我想出了以下代码:
class FooPool {
public:
FooPool(int size) {
foo_pool = new char[size * sizeof(FooOp)]; // what about FooOp alignment?
cur = 0;
}
~FooPool() { delete foo_pool; }
FooOp *New(const std::vector<char> &v, const std::string &s) {
return new (reinterpret_cast<FooOp*>(foo_pool) + cur) FooOp(v,s);
}
void Release() {
for (int i = 0; i < cur; ++i) {
(reinterpret_cast<FooOp*>(foo_pool)+i)->~FooOp();
}
cur = 0;
}
private:
char *foo_pool;
int cur;
};
这似乎可行,但我很确定我需要以某种方式注意FooOp 的对齐。此外,我什至不确定这种方法是否可行,因为操作不是 POD。
- 我的方法有缺陷吗? (很可能)
- 有什么更好的方法?
- 有没有办法使用
unique_ptrs 回收现有内存?
谢谢!
【问题讨论】:
-
您应该在使用placement new 时手动调用析构函数。是的,正如@vu1p3n0x 指出的那样,你不能破坏那个内存,因为你没有分配那个块,当你完成它时,你需要删除你用于池的整个块。
-
不要将
delete与placement new一起使用 -
@Cornstalks 我查看了
std::aligned_storage,但不幸的是它只是 c++17。关于放置新,我认为我在我的代码中正是这样做的,即new (addr) Ctor(...)。
标签: c++ c++11 memory-management pool