私は単純なメモリ アリーナ アロケーターを作成していて、例外の安全性に関する小さな問題に直面しています。状況は、それ自体がアロケーターを呼び出すオブジェクトを割り当てる場合です。メモリ プールの目的は、一度に多数のオブジェクトを割り当て、プールが破棄されたときにそれらをすべて削除することです。
{
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
しかし、内側の割り当てがクリーンアップされない場合、外側の割り当てもクリーンアップできません。これは、メモリ アリーナがハードウェア スタックのように線形に割り当てるため、メモリ リークが発生するためです。したがって、オブジェクトを早期に破棄してセマンティクスに違反するか、メモリ リークを起こします。
この問題を解決する方法について何か提案はありますか?