c++ - 从 lambda 返回 Eigen::Map

标签 c++ lambda eigen eigen3

从 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/

相关文章:

c++ - OS X Yosemite的SciTe-错误: cannot be used within an App Sandbox

c++ - 从 QT 资源加载 openCV Haar Cascade

C++二进制文件 - 一遍又一遍地写入相同的数字

c++ - 使用特征参数进行模板推导

c++ - 为什么 “using namespace std;”被视为不良做法?

python - 在 lambda 中使用导入函数 - Python

python - PyTorch 不能 pickle lambda

c# - 为什么 LINQ 不是纯函数式的?

c++ - Eigen 稀疏矩阵乘法的内存泄漏

c++ - 在 Eigen Solver 中从 Vector 中检索值