分段错误原因未知Opencv
Posted
技术标签:
【中文标题】分段错误原因未知Opencv【英文标题】:Segmentation Fault reason unknown Opencv 【发布时间】:2012-12-25 20:08:47 【问题描述】:我在 linux 终端(linux 中的 c++)中编译了以下代码,并且正在使用 OpenCv 2.4.3。
但是,运行时出现分段错误,我真的不知道为什么。我放置了不同的 cout 语句以了解程序是否处理到特定阶段但徒劳无功。请你帮助我好吗?请解释一下这个分段错误到底是什么。卡在这里很久了。
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <stdlib.h>
using namespace cv;
using namespace std;
int main()
cout<<"check"<<flush;
Mat src,src_gray,dst;
int kernel_size = 3;
int scale = 1;
int delta = 0;
int ddepth = CV_16S;
char* window_name = "sharpness estimate";
int freq,rows,cols =0;
double *estimate,*min = 0;
Point *minLoc,*maxLoc = 0;
src = imread("/home/siddarth/examplescv/erez images/image53.jpg");
if( !src.data )
return -1;
namedWindow(window_name,CV_WINDOW_AUTOSIZE);
Mat abs_dst;
cvtColor(src,src_gray,CV_RGB2GRAY);
Laplacian(src_gray,dst,ddepth,kernel_size,scale,delta,BORDER_DEFAULT);
convertScaleAbs(dst, abs_dst);
minMaxLoc(dst,min,estimate,minLoc,maxLoc,noArray());
Size s = dst.size();
rows = s.height;
cols = s.width;
cout<<rows<<endl<<cols<<endl;
for(int i=0;i<=rows;i++)
for(int j=0;j<=cols;j++)
if(dst.at<double>(i,j) >= *estimate-100
&& dst.at<double>(i,j) <= *estimate+100)
cout<<freq++;
cout<<"estimate :"<<*estimate<<endl;
cout<<"frequency :"<<freq<<endl;
imshow(window_name,abs_dst);
waitKey(1000);
return 0;
代码没有跨越主函数声明之后的第一个“检查”打印语句。这就是令人困惑的问题。但是一旦我刷新了第一个打印语句,它就被执行了。我仍然面临问题。
【问题讨论】:
那么您的cout
s 告诉了您什么?这里缺少很多东西。我们真的需要更多地了解它何时发生。
cout 什么也没给我。这就是整个混乱。也未达到初始检查。请帮帮我。
如果你在你的第一个 cout 中添加一个“endl”,我敢打赌它会打印出来,但它会在几行之后失败。尝试添加更多 cout 或在调试器中运行您的代码。这很可能是显而易见的!
只是给未来读者的提示:如果使用通常与 stdio 同步的 cerr,则不需要 flushing .
【参考方案1】:
确保将std::endl
插入cout
,以便刷新缓冲区。这可能就是您看不到任何输出的原因。
一个直接的问题是你的for
循环使用<=
来检查条件,这意味着你很可能已经结束了。但既然你使用的是at
,你应该会抛出一个异常(假设这个Mat
类型就像一个标准容器)。
此外,您正在创建大量指针以作为某些函数参数传递(例如,double* estimate
)。这实际上并没有给你一个 double
对象,只是一个指针。除非您将它们传递给的函数为您分配 double
(我希望不是这样),否则您做错了。你应该这样做:
double estimate;
minMaxLoc(/* ... */, &estimate, /* ... */);
您需要对通过输出参数获得的所有值执行此操作。
还有一点需要注意:int i, j = 0;
只会将j
初始化为0
,而不是i
。你需要做int i = 0, j = 0;
。
好的,我将解释为什么修复初始化程序有效。我不得不查找the definition of minMaxLoc 看看会发生什么。基本上,函数如下所示:
void setToFive(int* x)
if (x)
*x = 5;
此函数将获取一个指向int
的指针,然后将该int
设置为值5
。但是,如果传递的指针是空指针,则不会设置该值(否则将出现未定义的行为,因为您正在取消对空指针的引用)。基本上,传递一个空指针表示“我不关心这个值,所以不要给我”。
现在当你初始化你的指针时,你正在做:
double *estimate, *min = 0;
这只会将min
设置为空指针。由于estimate
未初始化,因此您不能依赖其值为空。你需要为每个声明器提供一个初始化器:
double *estimate = 0, *min = 0;
【讨论】:
是的,感谢您指出。但是代码甚至没有跨越 main 之后的第一个 check cout 语句。 @LakshmiNarayanan 确保您使用<< std::flush
或<< std::endl
刷新输出缓冲区。然后向我们提供您从中获得的信息。
是的,有一个小改动。但我不确定你希望我如何以及在哪里实现它。我在第一个检查语句中使用了它,仅打印了它,然后立即出现分段错误。
@LakshmiNarayanan 当您希望看到一些输出时,您需要刷新缓冲区。否则你不能保证你会得到任何输出。因此,将cout
s 放在代码中的各个位置,确保刷新它们,然后您会发现是哪一行导致了您的段错误。我觉得我的最新编辑会对你有所帮助。
它做到了:)。这是初始化。万分感谢。你能解释一下究竟是这个分段错误吗?【参考方案2】:
感谢@sftrabbit。问题是初始化。而不是
int freq,rows,cols=0;
变化是
int freq=0,rows=0,cols=0;
这消除了分段错误。非常感谢您的帮助:)。
【讨论】:
【参考方案3】:由于您处于 Linux 环境中,因此您可以使用 valgrind 准确找出发生分段错误的位置。只需在程序名称或执行程序的方式之前键入 valgrind。例如,如果您使用以下命令执行程序:
你好-打印
改为发出以下命令:
valgrind hello -print
我看到你已经解决了这个问题,但这可能对未来有帮助!
【讨论】:
以上是关于分段错误原因未知Opencv的主要内容,如果未能解决你的问题,请参考以下文章