我正在编写一个简单的内存竞技场分配器,并遇到一个异常安全的小问题。情况是当您分配一个本身称为分配器的对象时。内存池的目标是一次分配一堆对象,然后在销毁该池时将其全部删除。
{ 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
但是如果内部分配没有被清理,外部分配也不能被清理,因为内存领域像在硬件堆栈上那样线性地分配它们,所以我泄漏了内存。因此,要么我过早破坏对象就违反了我的语义,要么我泄漏了内存。
有关如何解决此问题的任何建议?