使用 Eigen::MatrixXf 作为函数 return 类型时出现分段错误

Segmentation fault on using Eigen::MatrixXf as function return type

我正在尝试 return 类型 Eigen::MatrixXf 的值,但这会导致分段错误。尝试调试时,我发现如果 return 类型是 floatint 之类的东西,在函数中具有相应的 return 值,则函数运行成功。我已经尝试从 here 的 Eigen 文档中诊断问题,但没有任何帮助。

MatrixXf& create_V_matrix(cv::Mat H) {
    // Gather V matrix
    MatrixXf v11 = get_vij_matrix(H, 0, 0);
    MatrixXf v12 = get_vij_matrix(H, 0, 1);
    MatrixXf v22 = get_vij_matrix(H, 1, 1);
    MatrixXf V;
    V << v12.transpose(),
        (v11-v12).transpose();
    return V;
}

MatrixXf get_vij_matrix(cv::Mat H, int i, int j) {
    // Create v matrix at i and j
    MatrixXf vij;
    vij <<  H.at<float>(0, i)*H.at<float>(0, j),
            H.at<float>(0, 1)*H.at<float>(1, j) +
            H.at<float>(1, i)*H.at<float>(0, j),
            H.at<float>(1, i)*H.at<float>(1, j),
            H.at<float>(2, i)*H.at<float>(0, j) +
            H.at<float>(0, i)*H.at<float>(2, j),
            H.at<float>(2, i)*H.at<float>(1, j) +
            H.at<float>(1, i)*H.at<float>(2, j),
            H.at<float>(2, i)*H.at<float>(2, j);
    return vij;
}

这导致 Segmentation fault(core dumped)create_V_matrix(cv::Mat H) 被调用。

在你的函数et_vij_matrix中,你需要在使用operator <<赋值之前设置MatrixXfvij的大小。否则,为 vij 分配的存储大小为零,您的分配将越界。我计算了您要分配的 6 个值,因此在分配之前需要 vij.resize(1,6)vij.resize(2,3)vij.resize(3,2)vij.resize(6,1)

同样,在分配来自 v11v12 的值之前,您的矩阵 V 不会调整大小。

最后,正如 , you're create_V_matrix returns a MatrixXf& reference to a local variable, which is undefined behavior. While it might work, it is not required to. See this Q&A 所指出的,以获得很好的解释。如果您担心副本,您可以而且应该依靠 RVO/copy 省略来删除无意义的副本。