Fix memory leak in Ref<Sparse>

This commit is contained in:
Gael Guennebaud 2016-12-05 16:59:30 +01:00
parent 8640ffac65
commit a6b971e291

View File

@ -185,20 +185,27 @@ class Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType
EIGEN_SPARSE_PUBLIC_INTERFACE(Ref) EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
template<typename Derived> template<typename Derived>
inline Ref(const SparseMatrixBase<Derived>& expr) inline Ref(const SparseMatrixBase<Derived>& expr) : m_hasCopy(false)
{ {
construct(expr.derived(), typename Traits::template match<Derived>::type()); construct(expr.derived(), typename Traits::template match<Derived>::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 // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
} }
template<typename OtherRef> template<typename OtherRef>
inline Ref(const RefBase<OtherRef>& other) { inline Ref(const RefBase<OtherRef>& other) : m_hasCopy(false) {
construct(other.derived(), typename Traits::template match<OtherRef>::type()); construct(other.derived(), typename Traits::template match<OtherRef>::type());
} }
~Ref() {
if(m_hasCopy) {
TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes);
obj->~TPlainObjectType();
}
}
protected: protected:
template<typename Expression> template<typename Expression>
@ -208,6 +215,7 @@ class Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType
{ {
TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes); TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes);
::new (obj) TPlainObjectType(expr); ::new (obj) TPlainObjectType(expr);
m_hasCopy = true;
Base::construct(*obj); Base::construct(*obj);
} }
else else
@ -221,11 +229,13 @@ class Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType
{ {
TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes); TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes);
::new (obj) TPlainObjectType(expr); ::new (obj) TPlainObjectType(expr);
m_hasCopy = true;
Base::construct(*obj); Base::construct(*obj);
} }
protected: protected:
char m_object_bytes[sizeof(TPlainObjectType)]; char m_object_bytes[sizeof(TPlainObjectType)];
bool m_hasCopy;
}; };
@ -293,20 +303,27 @@ class Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType
EIGEN_SPARSE_PUBLIC_INTERFACE(Ref) EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
template<typename Derived> template<typename Derived>
inline Ref(const SparseMatrixBase<Derived>& expr) inline Ref(const SparseMatrixBase<Derived>& expr) : m_hasCopy(false)
{ {
construct(expr.derived(), typename Traits::template match<Derived>::type()); construct(expr.derived(), typename Traits::template match<Derived>::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 // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
} }
template<typename OtherRef> template<typename OtherRef>
inline Ref(const RefBase<OtherRef>& other) { inline Ref(const RefBase<OtherRef>& other) : m_hasCopy(false) {
construct(other.derived(), typename Traits::template match<OtherRef>::type()); construct(other.derived(), typename Traits::template match<OtherRef>::type());
} }
~Ref() {
if(m_hasCopy) {
TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes);
obj->~TPlainObjectType();
}
}
protected: protected:
template<typename Expression> template<typename Expression>
@ -320,11 +337,13 @@ class Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType
{ {
TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes); TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes);
::new (obj) TPlainObjectType(expr); ::new (obj) TPlainObjectType(expr);
m_hasCopy = true;
Base::construct(*obj); Base::construct(*obj);
} }
protected: protected:
char m_object_bytes[sizeof(TPlainObjectType)]; char m_object_bytes[sizeof(TPlainObjectType)];
bool m_hasCopy;
}; };
namespace internal { namespace internal {