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;
}