I am trying to initialize Eigen::SparseMatrix A
by using malloc
like this
A.valuePtr() = static_cast<T*>(std::malloc(nnz*sizeof(T)));
A.innerIndexPtr() = static_cast<int*>(std::malloc(nnz*sizeof(int)));
but I get the error
error: lvalue required as left operand of assignment
for both statements. In case it matters, the function containing the lines takes a Eigen::SparseMatrix<T, Eigen::RowMajor>
by reference.
Can anyone help me with this? I'm using g++ 5.2.
EDIT:
The function valuePtr
of class SparseMatrix
is
inline Scalar* valuePtr() { return &m_data.value(0); }
Scalar
is a template paramter. m_data
is a protected variable of type CompressedStorage
whose method value(size_t i)
returns a reference to the ith member of its internal data array.
inline Scalar& value(size_t i) { return m_values[i]; }
So, I concluded that valuePtr()
returns the address of the first element of an array. I should, then, be able to allocate space for that array by malloc.
In case someone is interested, I include a link for reference - please see lines after 84, and 131. Eigen3 SparseMatrix class
The problem is most likely due to you trying to assign a object to a method!
You lines equate to:
A.valuePtr() = Sometype_Pointer;
, A.valuePTR()
will Call the Eigen::SparseMatrix::valuePTR
method(function) of object A.
If this method returns a pointer (T* A::valuePtr()
) then the pointer returned isn't what you want! the method would be returning a rvalue; an rvalue is not a lvalue that isn't the pointer contained in A, rather it's a temporary copy of the pointer.
You can't assign anything directly to it, just like you can't touch the people on a television screen.
I'm making a massive assumption that your trying to do what I described above, and that would be impossible unless that method looked like this:
T ** Eigen::SparseMatrix::valuePTR()
{
return &T;
}
*A.valuePtr() = static_cast<T*>(std::malloc(nnz*sizeof(T)));
However, note that using malloc is considered very, very out-dated for c++ objects, something like this line would be more correct *A.valuePtr() = static_cast(new T[nnz]));
Honestly I'm trying very hard to understand what your code is supposed to accomplish. And most people (including myself) will not be familair with this "Eigen" class. Though I think you may very-much misunderstand how it's supposed to be used.
Could you possibly provide a link to documentation, or an example of how your creating / using this class?
After some research I came across This article as well as This Question, could it be possible you need to use a MappedSparseMatrix
inline Scalar* valuePtr() { return &m_data.value(0); }
will return a rvalue pointer. This isn't the object held in m_data, nor is it the pointer used internally. It's a temporary copy of a pointer to an existing object, trying to say "make this temporary copy point to something else" doesn't make sense.
inline Scalar& value(size_t i) { return m_values[i]; }
In this case, the method returns a reference to an object, a reference is not a pointer - (though the &
often confuses people).
A reference can be understood as the original object, you don't need to dereference a reference. Consider the following.
int A;
int * A_p = &A;
int & A_r = A;
int & A_r_2 = *A_p;
//de-reference the pointer (to create a reference)
*A_p = 10; //A == 10
//Assign directly to A (via the reference)
A_r = 12; // A == 12
//assign directy to A (via the reference to A, that was taken from A_p
A_r_2 = 15; // A == 15
//attempt to de-reference a reference
*A_r = 10; //ERROR, A_r is not a pointer.
In short, The reference being returned isn't a pointer to the object (that already exists), rather it is the object. This would allow you to set the object to something, or call methods on the object using the .
operator, however you cannot re-allocate something that already exists, and as such is an error.
Please consider reading this article on the difference between rvale and lvalue's in C++ understanding rvalue and lvalue