|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define EIGEN_STACK_ALLOCATION_LIMIT 100000000 |
|
|
|
|
|
#include "main.h" |
|
|
|
|
|
struct my_exception |
|
|
{ |
|
|
my_exception() {} |
|
|
~my_exception() {} |
|
|
}; |
|
|
|
|
|
class ScalarWithExceptions |
|
|
{ |
|
|
public: |
|
|
ScalarWithExceptions() { init(); } |
|
|
ScalarWithExceptions(const float& _v) { init(); *v = _v; } |
|
|
ScalarWithExceptions(const ScalarWithExceptions& other) { init(); *v = *(other.v); } |
|
|
~ScalarWithExceptions() { |
|
|
delete v; |
|
|
instances--; |
|
|
} |
|
|
|
|
|
void init() { |
|
|
v = new float; |
|
|
instances++; |
|
|
} |
|
|
|
|
|
ScalarWithExceptions operator+(const ScalarWithExceptions& other) const |
|
|
{ |
|
|
countdown--; |
|
|
if(countdown<=0) |
|
|
throw my_exception(); |
|
|
return ScalarWithExceptions(*v+*other.v); |
|
|
} |
|
|
|
|
|
ScalarWithExceptions operator-(const ScalarWithExceptions& other) const |
|
|
{ return ScalarWithExceptions(*v-*other.v); } |
|
|
|
|
|
ScalarWithExceptions operator*(const ScalarWithExceptions& other) const |
|
|
{ return ScalarWithExceptions((*v)*(*other.v)); } |
|
|
|
|
|
ScalarWithExceptions& operator+=(const ScalarWithExceptions& other) |
|
|
{ *v+=*other.v; return *this; } |
|
|
ScalarWithExceptions& operator-=(const ScalarWithExceptions& other) |
|
|
{ *v-=*other.v; return *this; } |
|
|
ScalarWithExceptions& operator=(const ScalarWithExceptions& other) |
|
|
{ *v = *(other.v); return *this; } |
|
|
|
|
|
bool operator==(const ScalarWithExceptions& other) const |
|
|
{ return *v==*other.v; } |
|
|
bool operator!=(const ScalarWithExceptions& other) const |
|
|
{ return *v!=*other.v; } |
|
|
|
|
|
float* v; |
|
|
static int instances; |
|
|
static int countdown; |
|
|
}; |
|
|
|
|
|
ScalarWithExceptions real(const ScalarWithExceptions &x) { return x; } |
|
|
ScalarWithExceptions imag(const ScalarWithExceptions & ) { return 0; } |
|
|
ScalarWithExceptions conj(const ScalarWithExceptions &x) { return x; } |
|
|
|
|
|
int ScalarWithExceptions::instances = 0; |
|
|
int ScalarWithExceptions::countdown = 0; |
|
|
|
|
|
|
|
|
#define CHECK_MEMLEAK(OP) { \ |
|
|
ScalarWithExceptions::countdown = 100; \ |
|
|
int before = ScalarWithExceptions::instances; \ |
|
|
bool exception_thrown = false; \ |
|
|
try { OP; } \ |
|
|
catch (my_exception) { \ |
|
|
exception_thrown = true; \ |
|
|
VERIFY(ScalarWithExceptions::instances==before && "memory leak detected in " && EIGEN_MAKESTRING(OP)); \ |
|
|
} \ |
|
|
VERIFY(exception_thrown && " no exception thrown in " && EIGEN_MAKESTRING(OP)); \ |
|
|
} |
|
|
|
|
|
void memoryleak() |
|
|
{ |
|
|
typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,1> VectorType; |
|
|
typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,Dynamic> MatrixType; |
|
|
|
|
|
{ |
|
|
int n = 50; |
|
|
VectorType v0(n), v1(n); |
|
|
MatrixType m0(n,n), m1(n,n), m2(n,n); |
|
|
v0.setOnes(); v1.setOnes(); |
|
|
m0.setOnes(); m1.setOnes(); m2.setOnes(); |
|
|
CHECK_MEMLEAK(v0 = m0 * m1 * v1); |
|
|
CHECK_MEMLEAK(m2 = m0 * m1 * m2); |
|
|
CHECK_MEMLEAK((v0+v1).dot(v0+v1)); |
|
|
} |
|
|
VERIFY(ScalarWithExceptions::instances==0 && "global memory leak detected in " && EIGEN_MAKESTRING(OP)); \ |
|
|
} |
|
|
|
|
|
void test_exceptions() |
|
|
{ |
|
|
CALL_SUBTEST( memoryleak() ); |
|
|
} |
|
|
|