2016-02-26 21 views
1

分配空间,我想用malloc这样使用ValuePtr中()等为Eigen3稀疏矩阵

A.valuePtr() = static_cast<T*>(std::malloc(nnz*sizeof(T))); 
A.innerIndexPtr() = static_cast<int*>(std::malloc(nnz*sizeof(int))); 

初始化Eigen::SparseMatrix A,但我得到的错误

error: lvalue required as left operand of assignment 

两个语句。万一它很重要,包含这些行的函数将引用Eigen::SparseMatrix<T, Eigen::RowMajor>

任何人都可以帮助我吗?我正在使用g ++ 5.2。

编辑: SparseMatrix类的功能valuePtr

inline Scalar* valuePtr() { return &m_data.value(0); } 

Scalar是一个模板参数中。 m_dataCompressedStorage类型的受保护变量,其方法value(size_t i)参考返回给其内部数据数组的第i个成员。

inline Scalar& value(size_t i) { return m_values[i]; } 

所以,我的结论是valuePtr()返回一个数组的第一元素的地址。那么,我应该可以通过malloc为该数组分配空间。

如果有人有兴趣,我包括一个链接以供参考 - 请84后线,以及131 Eigen3 SparseMatrix class

+0

从未使用过Eigen,但我相当确定这不是初始化特征矩阵的方式。你应该阅读文档。 –

+0

我同意@BaummitAugen,但是我可能建议你完全避免malloc并使用新的和删除(或更好的,一个C++ 11 shared_ptr,或unique_ptr。 –

+0

@JohnBargman我用malloc因为这就是他们在Eigen内部使用。 –

回答

1

问题是最有可能是由于你想一个对象分配给一个方法!

你行等同于: A.valuePtr() = Sometype_Pointer;A.valuePTR()将调用对象A.

Eigen::SparseMatrix::valuePTR方法(功能)如果该方法返回一个指针(T* A::valuePtr())然后返回指针是不是你想要的!该方法将返回一个右值;一个右值不是左值这不是A中包含的指针,而是指针的临时副本
你不能直接指定任何东西,就像你不能在电视屏幕上触摸人物一样。

我做你想做什么上述我一个巨大的假设,这将是不可能的,除非该方法是这样的:

T ** Eigen::SparseMatrix::valuePTR() 
{ 
    return &T; 
} 
*A.valuePtr() = static_cast<T*>(std::malloc(nnz*sizeof(T))); 

但是请注意,使用malloc非常认为,非常过时的C++对象,像这样的行会更多正确 * A.valuePtr()= static_cast(new T [nnz]));

[编辑/]

老实说,我想很难理解你的代码应该完成。而且大多数人(包括我自己)不会成为这个“特征”类的家庭。尽管我认为你可能会误解它应该如何使用。

你能提供一个链接到文档,或者你如何创建/使用这个类的例子吗?

[编辑2 /]

一些研究,我碰到This article来到以及This Question,可以说,它是可能的,你需要使用一个MappedSparseMatrix

[编辑3 /]

inline Scalar* valuePtr() { return &m_data.value(0); }后,将返回一个右值指针。这不是m_data中的对象,也不是内部使用的指针。这是一个临时指向现有对象的指针副本,试图说“将此临时副本指向其他东西”是没有意义的。

inline Scalar& value(size_t i) { return m_values[i]; }在这种情况下,该方法返回一个引用对象,参考不是​​指针 - (虽然&经常混淆人)。
参考可以理解为原始对象,您不需要提领的一个参考。考虑以下。

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. 

总之,正在返回的参考不是一个指向对象(已经存在的),而它是对象。这将允许您将对象设置为某个对象,或者使用.运算符调用对象上的方法,但不能重新分配已存在的内容,因此是错误的。

请考虑阅读++ rvale和左值在C understanding rvalue and lvalue

+0

正确的做法的确是使用MappedSparseMatrix(3.2),或者更好的是使用特征3.3的Map >。 – ggael

+0

@John Bargman谢谢,MappedSparseMatrix工作 - 它有一个方便的构造函数来设置数组。但我仍不明白为什么我的早期方法不起作用。正如我在编辑中解释的那样,当我调用valuePtr()时,我应该得到一个左值。 –

+0

@AdityaKashi,我说holep真正valueptr,它返回一个指针,但是该指针是原始的'右值'副本 - 分配给它没有意义,因为它不会影响原始。 –

0

之间的差异这篇文章后@约翰Bargman告诉我,我想右值和左值的方式是错误的,我想过这个问题,并试图这样:

class A 
{ 
    char* str; 
public: 

    // This function returns a literal (constant) of type char* 
    // (just an address), not a pointer variable 
    char* getstr() { 
     return str; 
    } 

    char getchar(const int i) const { 
     return str[i]; 
    } 
}; 

int main() 
{ 
    A a; 

    // the RHS can't be assigned to a literal, we need a variable in the LHS 
    a.getstr() = static_cast<char*>(malloc(10*sizeof(char))); // ILLEGAL! 

    // this assigns the address contained in str to mstr. 
    char* mstr = a.getstr(); 

    // after this, mstr will have nothing to do with A::str; the former 
    // will have been re-assigned to a different address 
    mstr = static_cast<char*>(malloc(10*sizeof(char))); 

    for(int i = 0; i < 9; i++) 
     mstr[i] = '0'; 
    mstr[9] = '\0'; 

    // The following line segfaults as no storage has been allocated to A::str 
    cout << a.getchar(1) << endl; // runtime error! 

    free(mstr); 
    return 0; 
} 

现在我明白功能SparseMatrix::valuePtr(),如A::getstr(),返回一些地址类型的文字;它不返回一个左值。试图将一些东西(在这种情况下,由malloc返回的内存块的开始地址)分配给文字(在这种情况下,像0x233ff554这样的地址)是毫无意义的。我想我现在明白它是如何工作的。谢谢@John Bargman!