diff options
author | couriersud <couriersud@gmx.org> | 2019-04-22 21:08:46 +0200 |
---|---|---|
committer | couriersud <couriersud@gmx.org> | 2019-04-22 21:08:50 +0200 |
commit | 7cc3012c2249a352847e5470bef9d8a397eff4dd (patch) | |
tree | 4407488cc20054b2c075741cb0786c4de34d6b9d | |
parent | 56f9e77b84a5ea1400fe44d1048b356e47053616 (diff) |
netlist/plib: Fix memory leak when exception is thrown in constructor.
-rw-r--r-- | src/lib/netlist/plib/palloc.h | 17 | ||||
-rw-r--r-- | src/lib/netlist/plib/pmempool.h | 13 |
2 files changed, 28 insertions, 2 deletions
diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h index 15fede3a99b..d1b5eb28984 100644 --- a/src/lib/netlist/plib/palloc.h +++ b/src/lib/netlist/plib/palloc.h @@ -300,12 +300,29 @@ namespace plib { #endif } +#if 0 template<typename T, typename... Args> owned_pool_ptr<T> make_poolptr(Args&&... args) { auto *mem = allocate(alignof(T), sizeof(T)); return owned_pool_ptr<T>(new (mem) T(std::forward<Args>(args)...), true, arena_deleter<aligned_arena, T>(*this)); } +#endif + template<typename T, typename... Args> + owned_pool_ptr<T> make_poolptr(Args&&... args) + { + auto *mem = allocate(alignof(T), sizeof(T)); + try + { + auto *mema = new (mem) T(std::forward<Args>(args)...); + return owned_pool_ptr<T>(mema, true, arena_deleter<aligned_arena, T>(*this)); + } + catch (std::exception &e) + { + deallocate(mem); + throw e; + } + } }; diff --git a/src/lib/netlist/plib/pmempool.h b/src/lib/netlist/plib/pmempool.h index 2cceb18f9a0..171b75727c8 100644 --- a/src/lib/netlist/plib/pmempool.h +++ b/src/lib/netlist/plib/pmempool.h @@ -168,7 +168,6 @@ namespace plib { { b->m_num_alloc--; //printf("Freeing in block %p %lu\n", b, b->m_num_alloc); - sinfo().erase(it); if (b->m_num_alloc == 0) { mempool *mp = b->m_mempool; @@ -179,6 +178,7 @@ namespace plib { mp->m_blocks.erase(itb); plib::pdelete(b); } + sinfo().erase(it); } } @@ -189,7 +189,16 @@ namespace plib { owned_pool_ptr<T> make_poolptr(Args&&... args) { auto *mem = this->allocate(alignof(T), sizeof(T)); - return owned_pool_ptr<T>(new (mem) T(std::forward<Args>(args)...), true, arena_deleter<mempool, T>(this)); + try + { + auto *mema = new (mem) T(std::forward<Args>(args)...); + return owned_pool_ptr<T>(mema, true, arena_deleter<mempool, T>(this)); + } + catch (std::exception &e) + { + this->deallocate(mem); + throw e; + } } }; |