diff options
author | Moritz Klammler <moritz@klammler.eu> | 2014-07-06 06:58:13 +0200 |
---|---|---|
committer | Moritz Klammler <moritz@klammler.eu> | 2014-07-06 06:58:13 +0200 |
commit | 58687aa5e638d365d5e41c1e6c66cbfc44fce85f (patch) | |
tree | af5ea0fa2a0de994a4d3522e94ff83852e30adb0 /test/ctorleak.cpp | |
parent | 339f14b8d1b73db0366afc3a497d566cecf72e1b (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.cpp | 43 |
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 */ } +} |