mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-06-04 18:54:00 +08:00
Applied changes suggested by Christoph Hertzberg to c'tor leak fix.
- Enclose exception handling in '#ifdef EIGEN_EXCEPTIONS'. - Use an object counter to demonstrate the bug more readily.
This commit is contained in:
parent
58687aa5e6
commit
529e6cb552
@ -354,16 +354,20 @@ template<typename T> inline void destruct_elements_of_array(T *ptr, size_t size)
|
|||||||
template<typename T> inline T* construct_elements_of_array(T *ptr, size_t size)
|
template<typename T> inline T* construct_elements_of_array(T *ptr, size_t size)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
try
|
try
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
for (i = 0; i < size; ++i) ::new (ptr + i) T;
|
for (i = 0; i < size; ++i) ::new (ptr + i) T;
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
destruct_elements_of_array(ptr, i);
|
destruct_elements_of_array(ptr, i);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -385,30 +389,38 @@ template<typename T> inline T* aligned_new(size_t size)
|
|||||||
{
|
{
|
||||||
check_size_for_overflow<T>(size);
|
check_size_for_overflow<T>(size);
|
||||||
T *result = reinterpret_cast<T*>(aligned_malloc(sizeof(T)*size));
|
T *result = reinterpret_cast<T*>(aligned_malloc(sizeof(T)*size));
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
try
|
try
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
return construct_elements_of_array(result, size);
|
return construct_elements_of_array(result, size);
|
||||||
}
|
}
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
aligned_free(result);
|
aligned_free(result);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, bool Align> inline T* conditional_aligned_new(size_t size)
|
template<typename T, bool Align> inline T* conditional_aligned_new(size_t size)
|
||||||
{
|
{
|
||||||
check_size_for_overflow<T>(size);
|
check_size_for_overflow<T>(size);
|
||||||
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
|
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
try
|
try
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
return construct_elements_of_array(result, size);
|
return construct_elements_of_array(result, size);
|
||||||
}
|
}
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
conditional_aligned_free<Align>(result);
|
conditional_aligned_free<Align>(result);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal Deletes objects constructed with aligned_new
|
/** \internal Deletes objects constructed with aligned_new
|
||||||
@ -438,15 +450,19 @@ template<typename T, bool Align> inline T* conditional_aligned_realloc_new(T* pt
|
|||||||
T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
|
T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
|
||||||
if(new_size > old_size)
|
if(new_size > old_size)
|
||||||
{
|
{
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
try
|
try
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
construct_elements_of_array(result+old_size, new_size-old_size);
|
construct_elements_of_array(result+old_size, new_size-old_size);
|
||||||
}
|
}
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
conditional_aligned_free<Align>(result);
|
conditional_aligned_free<Align>(result);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -458,15 +474,19 @@ template<typename T, bool Align> inline T* conditional_aligned_new_auto(size_t s
|
|||||||
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
|
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
|
||||||
if(NumTraits<T>::RequireInitialization)
|
if(NumTraits<T>::RequireInitialization)
|
||||||
{
|
{
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
try
|
try
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
construct_elements_of_array(result, size);
|
construct_elements_of_array(result, size);
|
||||||
}
|
}
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
conditional_aligned_free<Align>(result);
|
conditional_aligned_free<Align>(result);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -480,15 +500,19 @@ template<typename T, bool Align> inline T* conditional_aligned_realloc_new_auto(
|
|||||||
T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
|
T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
|
||||||
if(NumTraits<T>::RequireInitialization && (new_size > old_size))
|
if(NumTraits<T>::RequireInitialization && (new_size > old_size))
|
||||||
{
|
{
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
try
|
try
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
construct_elements_of_array(result+old_size, new_size-old_size);
|
construct_elements_of_array(result+old_size, new_size-old_size);
|
||||||
}
|
}
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
conditional_aligned_free<Align>(result);
|
conditional_aligned_free<Align>(result);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,30 @@
|
|||||||
|
|
||||||
struct Foo
|
struct Foo
|
||||||
{
|
{
|
||||||
|
static unsigned object_count;
|
||||||
|
static unsigned object_limit;
|
||||||
int dummy;
|
int dummy;
|
||||||
Foo() { if (!internal::random(0, 10)) throw Foo::Fail(); }
|
|
||||||
|
Foo()
|
||||||
|
{
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
|
// TODO: Is this the correct way to handle this?
|
||||||
|
if (Foo::object_count > Foo::object_limit) { throw Foo::Fail(); }
|
||||||
|
#endif
|
||||||
|
++Foo::object_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Foo()
|
||||||
|
{
|
||||||
|
--Foo::object_count;
|
||||||
|
}
|
||||||
|
|
||||||
class Fail : public std::exception {};
|
class Fail : public std::exception {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned Foo::object_count = 0;
|
||||||
|
unsigned Foo::object_limit = 0;
|
||||||
|
|
||||||
namespace Eigen
|
namespace Eigen
|
||||||
{
|
{
|
||||||
template<>
|
template<>
|
||||||
@ -34,10 +53,17 @@ namespace Eigen
|
|||||||
|
|
||||||
void test_ctorleak()
|
void test_ctorleak()
|
||||||
{
|
{
|
||||||
|
Foo::object_count = 0;
|
||||||
|
Foo::object_limit = internal::random(0, 14 * 92 - 2);
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
try
|
try
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
Matrix<Foo, Dynamic, Dynamic> m(14, 92);
|
Matrix<Foo, Dynamic, Dynamic> m(14, 92);
|
||||||
eigen_assert(false); // not reached
|
eigen_assert(false); // not reached
|
||||||
}
|
}
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
catch (const Foo::Fail&) { /* ignore */ }
|
catch (const Foo::Fail&) { /* ignore */ }
|
||||||
|
#endif
|
||||||
|
VERIFY_IS_EQUAL(static_cast<unsigned>(0), Foo::object_count);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user