aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/ctorleak.cpp
diff options
context:
space:
mode:
authorGravatar Moritz Klammler <moritz@klammler.eu>2014-07-06 06:58:13 +0200
committerGravatar Moritz Klammler <moritz@klammler.eu>2014-07-06 06:58:13 +0200
commit58687aa5e638d365d5e41c1e6c66cbfc44fce85f (patch)
treeaf5ea0fa2a0de994a4d3522e94ff83852e30adb0 /test/ctorleak.cpp
parent339f14b8d1b73db0366afc3a497d566cecf72e1b (diff)
Avoid memory leak when constructor of user-defined type throws exception.
The added check `ctorleak.cpp` demonstrates how the leak can be reproduced. The test appears to pass but it is leaking the storage of the (not created) matrix. I don't know how to make this test fail in the existing test suite but you can run it through Valgrind (or another debugger) to verify the leak. $ ./check.sh ctorleak && valgrind --leak-check=full ./test/ctorleak This patch fixes this leak by adding some try-catch-delete-rethrow blocks to `Eigen/src/Core/util/Memory.h`.
Diffstat (limited to 'test/ctorleak.cpp')
-rw-r--r--test/ctorleak.cpp43
1 files changed, 43 insertions, 0 deletions
diff --git a/test/ctorleak.cpp b/test/ctorleak.cpp
new file mode 100644
index 000000000..72ab94b66
--- /dev/null
+++ b/test/ctorleak.cpp
@@ -0,0 +1,43 @@
+#include "main.h"
+
+#include <exception> // std::exception
+
+struct Foo
+{
+ int dummy;
+ Foo() { if (!internal::random(0, 10)) throw Foo::Fail(); }
+ class Fail : public std::exception {};
+};
+
+namespace Eigen
+{
+ template<>
+ struct NumTraits<Foo>
+ {
+ typedef double Real;
+ typedef double NonInteger;
+ typedef double Nested;
+ enum
+ {
+ IsComplex = 0,
+ IsInteger = 1,
+ ReadCost = -1,
+ AddCost = -1,
+ MulCost = -1,
+ IsSigned = 1,
+ RequireInitialization = 1
+ };
+ static inline Real epsilon() { return 1.0; }
+ static inline Real dummy_epsilon() { return 0.0; }
+ };
+}
+
+void test_ctorleak()
+{
+ try
+ {
+ Matrix<Foo, Dynamic, Dynamic> m(14, 92);
+ eigen_assert(false); // not reached
+ }
+ catch (const Foo::Fail&) { /* ignore */ }
+}