Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #define EIGEN_STACK_ALLOCATION_LIMIT 100000000
00031
00032 #include "main.h"
00033
00034 struct my_exception
00035 {
00036 my_exception() {}
00037 ~my_exception() {}
00038 };
00039
00040 class ScalarWithExceptions
00041 {
00042 public:
00043 ScalarWithExceptions() { init(); }
00044 ScalarWithExceptions(const float& _v) { init(); *v = _v; }
00045 ScalarWithExceptions(const ScalarWithExceptions& other) { init(); *v = *(other.v); }
00046 ~ScalarWithExceptions() {
00047 delete v;
00048 instances--;
00049 }
00050
00051 void init() {
00052 v = new float;
00053 instances++;
00054 }
00055
00056 ScalarWithExceptions operator+(const ScalarWithExceptions& other) const
00057 {
00058 countdown--;
00059 if(countdown<=0)
00060 throw my_exception();
00061 return ScalarWithExceptions(*v+*other.v);
00062 }
00063
00064 ScalarWithExceptions operator-(const ScalarWithExceptions& other) const
00065 { return ScalarWithExceptions(*v-*other.v); }
00066
00067 ScalarWithExceptions operator*(const ScalarWithExceptions& other) const
00068 { return ScalarWithExceptions((*v)*(*other.v)); }
00069
00070 ScalarWithExceptions& operator+=(const ScalarWithExceptions& other)
00071 { *v+=*other.v; return *this; }
00072 ScalarWithExceptions& operator-=(const ScalarWithExceptions& other)
00073 { *v-=*other.v; return *this; }
00074 ScalarWithExceptions& operator=(const ScalarWithExceptions& other)
00075 { *v = *(other.v); return *this; }
00076
00077 bool operator==(const ScalarWithExceptions& other) const
00078 { return *v==*other.v; }
00079 bool operator!=(const ScalarWithExceptions& other) const
00080 { return *v!=*other.v; }
00081
00082 float* v;
00083 static int instances;
00084 static int countdown;
00085 };
00086
00087 int ScalarWithExceptions::instances = 0;
00088 int ScalarWithExceptions::countdown = 0;
00089
00090
00091 #define CHECK_MEMLEAK(OP) { \
00092 ScalarWithExceptions::countdown = 100; \
00093 int before = ScalarWithExceptions::instances; \
00094 bool exception_thrown = false; \
00095 try { OP; } \
00096 catch (my_exception) { \
00097 exception_thrown = true; \
00098 VERIFY(ScalarWithExceptions::instances==before && "memory leak detected in " && EIGEN_MAKESTRING(OP)); \
00099 } \
00100 VERIFY(exception_thrown && " no exception thrown in " && EIGEN_MAKESTRING(OP)); \
00101 }
00102
00103 void memoryleak()
00104 {
00105 typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,1> VectorType;
00106 typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,Dynamic> MatrixType;
00107
00108 {
00109 int n = 50;
00110 VectorType v0(n), v1(n);
00111 MatrixType m0(n,n), m1(n,n), m2(n,n);
00112 v0.setOnes(); v1.setOnes();
00113 m0.setOnes(); m1.setOnes(); m2.setOnes();
00114 CHECK_MEMLEAK(v0 = m0 * m1 * v1);
00115 CHECK_MEMLEAK(m2 = m0 * m1 * m2);
00116 CHECK_MEMLEAK((v0+v1).dot(v0+v1));
00117 }
00118 VERIFY(ScalarWithExceptions::instances==0 && "global memory leak detected in " && EIGEN_MAKESTRING(OP)); \
00119 }
00120
00121 void test_exceptions()
00122 {
00123 CALL_SUBTEST( memoryleak() );
00124 }