使用 valuePtr() 等为 Eigen3 稀疏矩阵分配空间
Using valuePtr() etc to allocate space for Eigen3 SparseMatrix
我正在尝试使用这样的malloc
初始化Eigen::SparseMatrix A
A.valuePtr() = static_cast<T*>(std::malloc(nnz*sizeof(T)));
A.innerIndexPtr() = static_cast<int*>(std::malloc(nnz*sizeof(int)));
但我收到错误
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_data
是 CompressedStorage
类型的受保护变量,其方法value(size_t i)
返回对其内部数据数组的第 i 个成员的引用。
inline Scalar& value(size_t i) { return m_values[i]; }
因此,我得出结论,valuePtr()
返回数组第一个元素的地址。然后,我应该能够通过malloc为该数组分配空间。
如果有人感兴趣,我包含一个链接以供参考 - 请参阅84和131之后的行。Eigen3 稀疏矩阵类
问题很可能是由于您尝试将对象分配给方法!
您的行相当于: A.valuePtr() = Sometype_Pointer;
,A.valuePTR()
将调用对象 A 的 Eigen::SparseMatrix::valuePTR
方法(函数)。
如果此方法返回指针 ( T* A::valuePtr()
),则返回的指针不是您想要的! 该方法将返回一个 rvalue; 右值不是不是 A 中包含的指针的左值,而是指针的临时副本。
你不能直接给它分配任何东西,就像你不能触摸电视屏幕上的人一样。
做了一个巨大的假设,即您尝试执行我上面描述的操作,除非该方法如下所示,否则这是不可能的:
T ** Eigen::SparseMatrix::valuePTR()
{
return &T;
}
*A.valuePtr() = static_cast<T*>(std::malloc(nnz*sizeof(T)));
但是,请注意,对于 c++ 对象来说,使用 malloc 被认为是非常非常过时的,像这样一行的东西会更正确 *A.valuePtr() = static_cast(new T[nnz]));
[编辑/]
老实说,我正在努力理解您的代码应该完成什么。而大多数人(包括我自己)都不会熟悉这个"本征"类。虽然我认为你可能非常误解它应该如何使用。
您能否提供文档链接,或如何创建/使用此类的示例?
[编辑2/]
经过一些研究,我遇到了这篇文章以及这个问题,您是否需要使用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 和 lvalue 在理解 rvalue 和 lvalue 方面的区别C++
在@John巴格曼告诉我我对右值和左值的看法是错误的之后,我想了想并尝试了一下:
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] = ' ';
// 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巴格曼!
- STL算法和back_inserter可以预分配空间吗?
- 如何为结构字段动态分配字符空间
- 为阵列分配空间
- 如何为标准功能分配空间并做记忆
- 分配空间时,我会收到非常不同的地址
- 如何为字符串数组实例变量动态分配空间
- 在C++中根据需要为数据结构分配空间
- 函数在无法分配空间时返回值
- 更改 malloc 函数分配空间
- 使用 valuePtr() 等为 Eigen3 稀疏矩阵分配空间
- 正在为结构内部的列表分配空间
- 如果您使用new来分配空间,您必须在何时释放它
- 正在为返回的引用分配空间
- 为指向结构的指针的矢量分配空间
- 在C++构造函数中,我必须为实例字段分配空间吗
- 如何在Windows上为C/ c++中的文件预先分配空间
- 如何为未在协议中赋值的可选字段分配空间
- C++,在for循环中分配空间,可能进行内存泄漏验证
- 如何在现代C++中有效地为指向虚拟基类的指针向量分配空间
- 已分配空间中的链表