specialization of class SparseLU for UmfPack violates rule of three

Submitted by Maxim Ivanov

Assigned to Nobody

Link to original bugzilla bug (#438)
Version: 3.0

Description

In the source file unsupported/Eigen/src/SparseExtra/UmfPackSupport.h of Eigen version 3.0.1 one can find the specialization of class template SparseLU for UmfPack, which defines the following destructor:

~SparseLU()  

{  

  if (m_numeric)  

    umfpack_free_numeric(&m_numeric,Scalar());  

}  

where m_numeric is an opaque member pointer to Umfpack library data. This definition tries to provide some resource management of the data, however the class doesn't define a copy constructor nor the copy assignment operator, as the C++ rule of three suggests. This leaves the class with implicitly generated copy constructor and copy assignment operator which obviously don't handle the pointer in correct way.

This easily leads to incorrect behavior of the class in various situations, for example:

class Test {

Eigen::SparseMatrix<double> equations;  

Eigen::SparseLU<decltype(equations), Eigen::UmfPack> equations_lu;  

// ...  

public:

Test(...);  

};

Test::Test(...) {

// populate the default-constructed equations member  

// ...  



// perform the decomposition  

equations_lu = {equations};  



// ...  

}

In this (and notably many others) usage scenario equations_lu will have incorrect m_numeric value after the initialization.

My workaround to this bug was using the SparseLU::compute method to reinitialize equations_lu in-place.

I'd suggest using a smart pointer with custom allocator to manage the lifetime of m_numeric.

Blocking

#55 (closed)