【发布时间】:2012-01-25 09:28:20
【问题描述】:
我正在编写一个简单的内存区域分配器,并面临一个异常安全的小问题。这种情况是当您分配一个本身调用分配器的对象时。内存池的目的是一次分配一堆对象,然后在池被销毁时全部删除。
{
MemoryArena m;
std::string* ptr = m.Allocate<std::string>();
// use ptr whatever
// Cleaned up when pool is destroyed
}
但是当它被多次使用时会变得相当讨厌。如果内部分配被清理,那么它可以在之后使用——这不是一个坏的假设,因为池的定义是在它的生命周期结束之前永远不会删除对象。考虑:
struct X {
X(MemoryArena* ptr, std::string*& ref) {
ref = ptr->Allocate<std::string>();
throw std::runtime_error("hai");
}
};
MemoryArena m;
std::string* ptr;
m.Allocate<X>(&m, ptr);
// ptr is invalid- even though it came from the arena
// which hasn't yet been destroyed
但是如果内部分配没有清理,外部分配也无法清理,因为内存领域像在硬件堆栈上一样线性分配它们,所以我泄漏内存。所以要么我提前销毁一个对象违反了我的语义,要么我泄漏了内存。
对于如何解决这个问题有什么建议吗?
【问题讨论】:
-
什么是
MemoryArena?我们怎么能在不知情的情况下说出任何话呢? -
目前还不清楚你是如何泄漏内存的,当 arena 被释放时它会被释放。
-
@zvrba:已分配,但无法使用,因为对象从未构造过,指针也从未返回,所以内存一直泄漏,直到区域被销毁。
-
@DeadMG:
MemoryArena的实现是什么?该信息不在问题范围内。 -
不需要实现。这对我来说似乎是一个设计问题。基本上是问如何在不违反某些语义和泄漏内存的情况下实现它。
标签: c++ c++11 exception-safety