使用 Eigen::Map 构建矩阵时函数内部向量的内存分配
Memory allocation of a vector inside a function while building matrices with Eigen::Map
我创建了一个 class 来读取向量并将结果复制到所需的矩阵(实际上它将字符串更改为向量并且解析的向量大小未知,但我 post 一个简化的代码)。
函数 getMatrix
读取一个向量,将其复制到向量 containerVector
并使用函数 Map
将其重塑为矩阵,containerMatrix
通过-参考。但是,在执行该函数后,对象 containerVector
被销毁,据我了解 Eigen Map tutorial,containerMatrix
指向任何地方(或指向内存中的某个随机位置)。因此,当我执行第二个函数 setModelMatrix 时,它应该 return 某些内存分配错误或分段错误。但是,它工作正常,所以看起来值是被复制的,而不是传递的。以这种方式使用 Map 是否安全,还是我只是幸运?我的理解是否正确,或者是否有更好的解决方案?
注意:我将针对不同的向量多次使用函数getMatrix
,并将获得的值复制到不同的矩阵,这些不包含在代码的呈现部分中。逗号初始值设定项对我的问题不起作用。
class MatrixModificationClass
{
private:
//two matrices defined
MatrixXd containerMatrix; //a container
MatrixXd modelMatrix; //the proper matrix
public:
MatrixModificationClass();
//a function to create vector and map it to matrix
void getMatrix(std::vector ivector)
{
std::vector<double> containerVector;
//This is only a simplified example, in reality I change string to a vector
containerVector=ivector;
int instances=10, columns=10; //size of matrix
containerMatrix = MatrixXd::Map(&containerVector[0], columns, instances);
containerMatrix.transposeInPlace();
};
void setModelMatrix()
{
modelMatrix = containerMatrix;
};
};
main()
{
std::vector newVector;
MatrixModificationClass Example;
for (int i = 1; i <= 100; i++)
newVector.push_back(i);
Example.getMatrix(newVector);
Example.setModelMatrix();
}
您的代码是安全的(尽管不是最优的)。
在这一行
containerMatrix = MatrixXd::Map(&containerVector[0], columns, instances);
创建指向 &containerVector[0]
的 Eigen::Map
对象,然后将其内容复制到 containerMatrix
(MatrixXd
对象始终拥有其数据)。然后 Eigen::Map
被破坏(它在 ;
处超出范围),而 containerVector
仅在方法结束时被破坏。
作为一个简单的优化,可以通过直接赋值
来避免transposeInPlace()
containerMatrix = MatrixXd::Map(&containerVector[0], columns, instances).transpose();
根据您 "change string to a vector" 的方式,您可能可以直接写入 containerMatrix
(您需要在执行此操作之前将其调整为正确的尺寸)。
您还可以将 containerVector
存储在 class 中(而不是 containerMatrix
),并在需要时即时创建一个 Eigen::Map
。
不过,最有效的解决方案取决于您的实际用例。
我创建了一个 class 来读取向量并将结果复制到所需的矩阵(实际上它将字符串更改为向量并且解析的向量大小未知,但我 post 一个简化的代码)。
函数 getMatrix
读取一个向量,将其复制到向量 containerVector
并使用函数 Map
将其重塑为矩阵,containerMatrix
通过-参考。但是,在执行该函数后,对象 containerVector
被销毁,据我了解 Eigen Map tutorial,containerMatrix
指向任何地方(或指向内存中的某个随机位置)。因此,当我执行第二个函数 setModelMatrix 时,它应该 return 某些内存分配错误或分段错误。但是,它工作正常,所以看起来值是被复制的,而不是传递的。以这种方式使用 Map 是否安全,还是我只是幸运?我的理解是否正确,或者是否有更好的解决方案?
注意:我将针对不同的向量多次使用函数getMatrix
,并将获得的值复制到不同的矩阵,这些不包含在代码的呈现部分中。逗号初始值设定项对我的问题不起作用。
class MatrixModificationClass
{
private:
//two matrices defined
MatrixXd containerMatrix; //a container
MatrixXd modelMatrix; //the proper matrix
public:
MatrixModificationClass();
//a function to create vector and map it to matrix
void getMatrix(std::vector ivector)
{
std::vector<double> containerVector;
//This is only a simplified example, in reality I change string to a vector
containerVector=ivector;
int instances=10, columns=10; //size of matrix
containerMatrix = MatrixXd::Map(&containerVector[0], columns, instances);
containerMatrix.transposeInPlace();
};
void setModelMatrix()
{
modelMatrix = containerMatrix;
};
};
main()
{
std::vector newVector;
MatrixModificationClass Example;
for (int i = 1; i <= 100; i++)
newVector.push_back(i);
Example.getMatrix(newVector);
Example.setModelMatrix();
}
您的代码是安全的(尽管不是最优的)。
在这一行
containerMatrix = MatrixXd::Map(&containerVector[0], columns, instances);
创建指向 &containerVector[0]
的 Eigen::Map
对象,然后将其内容复制到 containerMatrix
(MatrixXd
对象始终拥有其数据)。然后 Eigen::Map
被破坏(它在 ;
处超出范围),而 containerVector
仅在方法结束时被破坏。
作为一个简单的优化,可以通过直接赋值
来避免transposeInPlace()
containerMatrix = MatrixXd::Map(&containerVector[0], columns, instances).transpose();
根据您 "change string to a vector" 的方式,您可能可以直接写入 containerMatrix
(您需要在执行此操作之前将其调整为正确的尺寸)。
您还可以将 containerVector
存储在 class 中(而不是 containerMatrix
),并在需要时即时创建一个 Eigen::Map
。
不过,最有效的解决方案取决于您的实际用例。