从 lambda 函数返回 Eigen::Map 会给出错误的输出:
#include<iostream>
#include<eigen3/Eigen/Dense>
using namespace std;
using namespace Eigen;
int main(){
auto doIt = [](){
MatrixXd a = MatrixXd::Random(2,3);
Map<MatrixXd> m(a.data(),2,3);
cout << "a:\n" << a << endl;
cout << "m:\n" << m << endl;
return m;
};
MatrixXd o(2,3);
o = doIt();
cout << "o:\n" << o << endl;
return 0;
}
输出(使用 Eigen 3.2.9-1):
a:
0.680375 0.566198 0.823295
-0.211234 0.59688 -0.604897
m:
0.680375 0.566198 0.823295
-0.211234 0.59688 -0.604897
o:
5.15038e-317 0.566198 0.823295
-0.211234 0.59688 -0.604897
如果使用 clang++ -std=c++11 -fsanitize=address
编译,我会进一步得到 heap-use-after-free-error。 (clang 版本 3.7.1)
如果我将 lambda 转换为返回 Eigen::MatrixXd
的函数,它会起作用——可能是因为额外的复制。有没有办法让它在 lambda 内部工作,而不使用额外的 MatrixXd
并将 map 的内容复制到它?
(在我的用例中,lambda 只能访问 Map m
而不能访问 MatrixXd a
本身)。
最佳答案
Map
不拥有数据,它只包装现有数据。如果数据被释放或修改,Map
将不会被察觉。而这正是这里发生的事情:
auto doIt = [](){
// Here MatrixXd dynamically allocates memory for its content
MatrixXd a = MatrixXd::Random(2,3);
// Now you save pointer to this allocated memory
Map<MatrixXd> m(a.data(),2,3);
cout << "a:\n" << a << endl;
cout << "m:\n" << m << endl;
return m;
// When leaving the scope via return or simple end of block
// all local variables will be destroyed.
// When destorying, Matrix will also free
// what it owns thus Map will point to invalid memory
};
所以基本上你正在访问一个释放的内存。您需要返回拥有资源的对象:
auto doIt = [](){
return MatrixXd::Random(2,3);
};
auto a = doIt();
Map<MatrixXd> m(a.data(),2,3);
cout << "a:\n" << a << endl;
cout << "m:\n" << m << endl;
MatrixXd o(2,3);
cout << "o:\n" << o << endl;
关于c++ - 从 lambda 返回 Eigen::Map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38786856/