2016-02-26 19 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!