C++ 使用valuePtr()等为Eigen3 SparseMatrix分配空间

C++ 使用valuePtr()等为Eigen3 SparseMatrix分配空间,c++,eigen,eigen3,C++,Eigen,Eigen3,我正试图像这样使用malloc初始化Eigen::SparseMatrix A A.valuePtr() = static_cast<T*>(std::malloc(nnz*sizeof(T))); A.innerIndexPtr() = static_cast<int*>(std::malloc(nnz*sizeof(int))); 对于这两种说法。如果有关系,则包含这些行的函数通过引用获取一个Eigen::SparseMatrix 有人能帮我吗?我使用的是g++5.

我正试图像这样使用
malloc
初始化
Eigen::SparseMatrix A

A.valuePtr() = static_cast<T*>(std::malloc(nnz*sizeof(T)));
A.innerIndexPtr() = static_cast<int*>(std::malloc(nnz*sizeof(int)));
对于这两种说法。如果有关系,则包含这些行的函数通过引用获取一个
Eigen::SparseMatrix

有人能帮我吗?我使用的是g++5.2

编辑: 类
SparseMatrix
的函数
valuePtr

inline Scalar* valuePtr() { return &m_data.value(0); }
Scalar
是一个模板参数
m_data
是一个类型为
CompressedStorage
的受保护变量,其方法
value(size\t i)
引用返回给其内部数据数组的第i个成员

 inline Scalar& value(size_t i) { return m_values[i]; }
因此,我得出结论,
valuePtr()
返回数组第一个元素的地址。那么,我应该能够通过malloc为该数组分配空间


如果有人感兴趣,我会提供一个链接供参考——请参阅84、131和131后面的行

问题很可能是由于您试图将对象分配给方法

您的行等同于:
A.valuePtr()=Sometype\u指针
A.valuePTR()
将调用对象A的
Eigen::SparseMatrix::valuePTR
方法(函数)

如果此方法返回指针(
T*a::valuePtr()
),则返回的指针不是您想要的!该方法将返回一个右值;右值不是不是不是包含在中的指针的左值,而是指针的临时副本。
你不能直接给它分配任何东西,就像你不能触摸电视屏幕上的人一样

我做了一个巨大的假设,你试图做我上面描述的事情,那是不可能的,除非这个方法是这样的:

T ** Eigen::SparseMatrix::valuePTR()
{
    return &T;
}
*A.valuePtr() = static_cast<T*>(std::malloc(nnz*sizeof(T)));
简而言之,返回的引用不是指向对象(已经存在)的指针,而是对象。这将允许您将对象设置为某个对象,或者使用
操作符调用对象上的方法,但是您不能重新分配已经存在的对象,因此这是一个错误


请阅读这篇文章,关于C++中的RVale与LVals之间的差异。@ John Bargman告诉我,我认为Roals/LoValy的方式是错误的,我想了想,尝试了:
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;
}
A类
{
char*str;
公众:
//此函数返回char*类型的文本(常量)
//(只是一个地址),而不是指针变量
char*getstr(){
返回str;
}
char getchar(const int i)const{
返回str[i];
}
};
int main()
{
A A;
//RHS不能分配给文字,我们需要在LHS中有一个变量
a、 getstr()=static_cast(malloc(10*sizeof(char));//非法!
//这会将str中包含的地址分配给mstr。
char*mstr=a.getstr();
//在此之后,mstr将与A::str无关;前者
//将被重新分配到其他地址
mstr=静态(malloc(10*sizeof(char));
对于(int i=0;i<9;i++)
mstr[i]=“0”;
mstr[9]='\0';
//由于没有将存储分配给::str,下面的行将显示错误

我从来没有使用过Eigen,但我相当确定这不是初始化Eigen矩阵的方式。你应该阅读文档。我同意@BaummitAugen,但是我可以建议你完全避免使用malloc,使用new和delete吗(或者更好,一个C++11共享的或唯一的\u ptr。@JohnBargman我使用malloc,因为这是他们在Eigen中内部使用的。我认为这对他们的析构函数更好。@BaummitAugen我知道这是非标准的。我需要它,因为我有自己的稀疏矩阵实现,我想与Eigen的稀疏LU分解例程一起使用。@AdityaKashi我想你可能真的想要这样:正确的方法确实是使用
MappedSparseMatrix
(使用3.2),或者最好是一个带有Eigen 3.3的
Map
。@John Bargman谢谢,MappedSparseMatrix可以工作-它有一个方便的构造函数来设置数组。但是我仍然不明白为什么我以前的方法不起作用。正如我在编辑中解释的,当我调用valuePtr()时,我应该得到一个左值@AdityaKashi,我所说的对于valueptr是正确的,它返回一个指针,但是该指针是原始指针的“右值”副本-分配给它没有意义,因为它不会影响原始值。@AdityaKashi,至于值(int)方法,该方法返回对对象的引用,但对象是实际对象。int&与int*不同。我将很快更新我的答案。
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.
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;
}