mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 00:30:49 +00:00
Fixed memory leak [#METR-2944].
This commit is contained in:
parent
8b1d686254
commit
39f2527012
@ -5,36 +5,55 @@
|
||||
namespace ext
|
||||
{
|
||||
|
||||
/**
|
||||
* Class AllocateShared allow to make std::shared_ptr<T> from T with private constructor.
|
||||
* Derive your T class from shared_ptr_helper<T>, define him as friend and call allocate_shared()/make_shared() method.
|
||||
**/
|
||||
template <class T>
|
||||
/** Class AllocateShared allow to make std::shared_ptr<T> from T with private constructor.
|
||||
* Derive your T class from shared_ptr_helper<T>, define him as friend and call allocate_shared()/make_shared() method.
|
||||
*/
|
||||
template <typename T>
|
||||
class shared_ptr_helper
|
||||
{
|
||||
protected:
|
||||
typedef typename std::remove_const<T>::type TNoConst;
|
||||
|
||||
template <class TAlloc>
|
||||
template <typename TAlloc>
|
||||
struct Deleter
|
||||
{
|
||||
void operator()(typename TAlloc::value_type * ptr)
|
||||
{
|
||||
std::allocator_traits<TAlloc>::destroy(alloc, ptr);
|
||||
using AllocTraits = std::allocator_traits<TAlloc>;
|
||||
ptr->~TNoConst();
|
||||
AllocTraits::deallocate(alloc, ptr, 1);
|
||||
}
|
||||
|
||||
TAlloc alloc;
|
||||
};
|
||||
|
||||
///see std::allocate_shared
|
||||
template <class TAlloc, class ... TArgs>
|
||||
static std::shared_ptr<T> allocate_shared(const TAlloc & alloc, TArgs && ... args)
|
||||
/// see std::allocate_shared
|
||||
template <typename TAlloc, typename ... TArgs>
|
||||
static std::shared_ptr<T> allocate_shared(const TAlloc & alloc, TArgs &&... args)
|
||||
{
|
||||
using AllocTraits = std::allocator_traits<TAlloc>;
|
||||
TAlloc alloc_copy(alloc);
|
||||
return std::shared_ptr<TNoConst>(new (std::allocator_traits<TAlloc>::allocate(alloc_copy, 1)) TNoConst(std::forward<TArgs>(args)...), Deleter<TAlloc>(), alloc_copy);
|
||||
|
||||
auto ptr = AllocTraits::allocate(alloc_copy, 1);
|
||||
|
||||
try
|
||||
{
|
||||
new (ptr) TNoConst(std::forward<TArgs>(args)...);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
AllocTraits::deallocate(alloc_copy, ptr, 1);
|
||||
throw;
|
||||
}
|
||||
|
||||
return std::shared_ptr<TNoConst>(
|
||||
ptr,
|
||||
Deleter<TAlloc>(),
|
||||
alloc_copy);
|
||||
}
|
||||
|
||||
template <class ... TArgs>
|
||||
static std::shared_ptr<T> make_shared(TArgs && ... args)
|
||||
template <typename ... TArgs>
|
||||
static std::shared_ptr<T> make_shared(TArgs &&... args)
|
||||
{
|
||||
return allocate_shared(std::allocator<TNoConst>(), std::forward<TArgs>(args)...);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user