summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2019-04-22 21:08:46 +0200
committer couriersud <couriersud@gmx.org>2019-04-22 21:08:50 +0200
commit7cc3012c2249a352847e5470bef9d8a397eff4dd (patch)
tree4407488cc20054b2c075741cb0786c4de34d6b9d
parent56f9e77b84a5ea1400fe44d1048b356e47053616 (diff)
netlist/plib: Fix memory leak when exception is thrown in constructor.
-rw-r--r--src/lib/netlist/plib/palloc.h17
-rw-r--r--src/lib/netlist/plib/pmempool.h13
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;
+ }
}
};