【发布时间】:2015-10-30 08:34:35
【问题描述】:
尝试调试一些利用 opencv 库的 c++11 代码,会在 gdb 中产生分段错误。
我正在使用 linux 中的 gdb 调试以下功能。
MatchedFeatures extract_best_features(vector<Mat> imgs)
{
MatchedFeatures result;
cv::Ptr<Feature2D> f2d = xfeatures2d::SIFT::create();
//cv::Ptr<Feature2D> f2d = xfeatures2d::SURF::create();
//cv::Ptr<Feature2D> f2d = ORB::create();
for (auto it = 0; it < imgs.size(); ++it) {
vector<KeyPoint> keyPoints;
Mat descriptors;
f2d->detect(imgs[it], keyPoints);
f2d->compute(imgs[it], keyPoints, descriptors);
result.imgFeatures.push_back(ImgFeatures{imgs[it], keyPoints, descriptors});
}
BFMatcher matcher;
vector< DMatch > matches;
matcher.match(result.imgFeatures[0].descriptors,
result.imgFeatures[1].descriptors,
matches);
cout << matches.size() << "\n";
//extract top 10
sort(matches.begin(), matches.end(),
[&](const DMatch x, const DMatch y) -> bool
{ return x.distance <= y.distance; });
result.matches = vector<DMatch>(matches.begin(),matches.begin()+5); // <- debug fails here and matches is empty in debug mode
return result;
}
当调试器到达我对matches 向量进行切片的点时,就会产生分段错误。检查matches 变量并查看堆栈跟踪发现matches 是空的。但是,仅在调试模式下为空。
代码在我正常运行时运行良好,只有在调试时失败。
我注意到 BFMatcher 在执行匹配时产生了很多线程,所以我怀疑问题是由线程引起的。虽然我刚开始学习c++,所以我只能猜测是哪里出了问题。
有什么方法可以“等待”线程在 gdb 中正确完成吗?
或者是否有其他技巧可以让我在 C++ 中调试和检查此类代码,而不会出现分段错误和来自副作用生成过程的空结果,例如 BFMatcher 中的 match?
编辑(解决了问题):
显然,在 cgdb 中运行程序时使用文件路径作为参数时应该使用完整路径(而不是使用主文件夹快捷方式 ~/ 的可执行文件的相对路径或路径)......我现在能够调试我的程序非常好..
【问题讨论】:
-
如何确保
matches中有5 个项目?更好的测试是:size_t lastItem = std::min(matches.size(), 5);,然后是vector<DMatch>(matches.begin(), matches.begin() + lastItem) -
同样的事情:
matcher.match(result.imgFeatures[0].descriptors, result.imgFeatures[1].descriptors,您假设您在imageFeatures中至少有 2 个项目。如果只有 1 个项目或为空怎么办?您正在访问越界的元素。添加第一条评论,再加上我给出的答案,你的代码有很多明显的问题,而线程没有问题。 -
matches.begin(),matches.begin()+5在计算该行之前,您可以验证matches.size 是6 还是更大?也许在调试模式下,由于路径错误或某事,您没有成功读取图像,可能导致空或不同的匹配向量。 -
啊好吧,你已经看到matches是空的。所以分析一下为什么在调试模式下if不同。由于错误的相对路径,可能候选人仍然是您确实阅读了不同的图像或根本没有图像。尝试显示中间结果等...