From ea56d2ff2ca8f102300ff4c34d8534f0ed55f1dd Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Mon, 5 Dec 2016 16:59:30 +0100 Subject: [PATCH] Fix memory leak in Ref (grafted from a6b971e291e9eb980eb94fa7d701f7b757dbcbd0 ) --- Eigen/src/SparseCore/SparseRef.h | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/Eigen/src/SparseCore/SparseRef.h b/Eigen/src/SparseCore/SparseRef.h index a558230e7..d91f38f97 100644 --- a/Eigen/src/SparseCore/SparseRef.h +++ b/Eigen/src/SparseCore/SparseRef.h @@ -185,20 +185,27 @@ class Ref, Options, StrideType EIGEN_SPARSE_PUBLIC_INTERFACE(Ref) template - inline Ref(const SparseMatrixBase& expr) + inline Ref(const SparseMatrixBase& expr) : m_hasCopy(false) { construct(expr.derived(), typename Traits::template match::type()); } - inline Ref(const Ref& other) : Base(other) { + inline Ref(const Ref& other) : Base(other), m_hasCopy(false) { // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy } template - inline Ref(const RefBase& other) { + inline Ref(const RefBase& other) : m_hasCopy(false) { construct(other.derived(), typename Traits::template match::type()); } + ~Ref() { + if(m_hasCopy) { + TPlainObjectType* obj = reinterpret_cast(m_object_bytes); + obj->~TPlainObjectType(); + } + } + protected: template @@ -208,6 +215,7 @@ class Ref, Options, StrideType { TPlainObjectType* obj = reinterpret_cast(m_object_bytes); ::new (obj) TPlainObjectType(expr); + m_hasCopy = true; Base::construct(*obj); } else @@ -221,11 +229,13 @@ class Ref, Options, StrideType { TPlainObjectType* obj = reinterpret_cast(m_object_bytes); ::new (obj) TPlainObjectType(expr); + m_hasCopy = true; Base::construct(*obj); } protected: char m_object_bytes[sizeof(TPlainObjectType)]; + bool m_hasCopy; }; @@ -293,20 +303,27 @@ class Ref, Options, StrideType EIGEN_SPARSE_PUBLIC_INTERFACE(Ref) template - inline Ref(const SparseMatrixBase& expr) + inline Ref(const SparseMatrixBase& expr) : m_hasCopy(false) { construct(expr.derived(), typename Traits::template match::type()); } - inline Ref(const Ref& other) : Base(other) { + inline Ref(const Ref& other) : Base(other), m_hasCopy(false) { // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy } template - inline Ref(const RefBase& other) { + inline Ref(const RefBase& other) : m_hasCopy(false) { construct(other.derived(), typename Traits::template match::type()); } + ~Ref() { + if(m_hasCopy) { + TPlainObjectType* obj = reinterpret_cast(m_object_bytes); + obj->~TPlainObjectType(); + } + } + protected: template @@ -320,11 +337,13 @@ class Ref, Options, StrideType { TPlainObjectType* obj = reinterpret_cast(m_object_bytes); ::new (obj) TPlainObjectType(expr); + m_hasCopy = true; Base::construct(*obj); } protected: char m_object_bytes[sizeof(TPlainObjectType)]; + bool m_hasCopy; }; namespace internal {