使用 Eigen::MatrixXf 作为函数 return 类型时出现分段错误
Segmentation fault on using Eigen::MatrixXf as function return type
我正在尝试 return 类型 Eigen::MatrixXf
的值,但这会导致分段错误。尝试调试时,我发现如果 return 类型是 float
或 int
之类的东西,在函数中具有相应的 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 <<
赋值之前设置MatrixXf
vij
的大小。否则,为 vij
分配的存储大小为零,您的分配将越界。我计算了您要分配的 6 个值,因此在分配之前需要 vij.resize(1,6)
、vij.resize(2,3)
、vij.resize(3,2)
或 vij.resize(6,1)
。
同样,在分配来自 v11
和 v12
的值之前,您的矩阵 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 省略来删除无意义的副本。
我正在尝试 return 类型 Eigen::MatrixXf
的值,但这会导致分段错误。尝试调试时,我发现如果 return 类型是 float
或 int
之类的东西,在函数中具有相应的 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 <<
赋值之前设置MatrixXf
vij
的大小。否则,为 vij
分配的存储大小为零,您的分配将越界。我计算了您要分配的 6 个值,因此在分配之前需要 vij.resize(1,6)
、vij.resize(2,3)
、vij.resize(3,2)
或 vij.resize(6,1)
。
同样,在分配来自 v11
和 v12
的值之前,您的矩阵 V
不会调整大小。
最后,正如 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 省略来删除无意义的副本。