0

我在 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;   
 }

代码不会在主函数声明之后越过第一个“检查”打印语句。这就是令人困惑的问题。但是一旦我刷新了第一个打印语句,它就被执行了。我仍然面临问题。

4

3 回答 3

4

确保插入std::endlcout以便刷新缓冲区。这可能就是您没有看到任何输出的原因。

一个直接的问题是您的for循环使用 来检查条件<=,这意味着您可能会超过最后一个。但是由于您使用的是at,因此应该抛出异常(假设此Mat类型的行为类似于标准容器)。

此外,您正在创建大量指针以作为某些函数参数传递(例如,double* estimate)。这实际上并没有给你一个double对象,只是一个指针。除非您将它们传递给的函数double为您分配 a(我希望不是),否则您做错了。你应该这样做:

double estimate;
minMaxLoc(/* ... */, &estimate, /* ... */);

您需要使用通过输出参数获得的所有值来执行此操作。

另一件需要注意的事情:只对 进行int i, j = 0;初始化,而不是对. 你需要做。j0iint i = 0, j = 0;


好的,我将解释为什么修复初始化程序有效。我不得不查看minMaxLoc 的定义以了解会发生什么。基本上,该功能类似于以下内容:

void setToFive(int* x)
{
  if (x) {
    *x = 5;
  }
}

该函数将获取一个指向 a 的指针int,然后将其设置int为 value 5。但是,如果传递的指针是空指针,则不会设置该值(否则将出现未定义的行为,因为您正在取消对空指针的引用)。基本上,传递一个空指针表示“我不在乎这个值,所以不要给我”。

现在,当您初始化指针时,您正在执行以下操作:

double *estimate, *min = 0;

这仅设置min为空指针。由于estimate未初始化,因此您不能依赖其值为 null。您需要为每个声明器提供一个初始化程序:

double *estimate = 0, *min = 0;
于 2012-12-25T20:10:42.490 回答
1

感谢@sftrabbit。问题是初始化。代替

    int freq,rows,cols=0;

变化是

    int freq=0,rows=0,cols=0; 

这消除了分段错误。非常感谢你的帮助 :)。

于 2012-12-25T20:28:46.453 回答
1

由于您处于 Linux 环境中,因此您可以使用 valgrind 准确找出发生分段错误的位置。只需在程序名称或执行程序的方式之前键入 valgrind。例如,如果您使用以下命令执行程序:

你好-打印

发出以下命令:

valgrind 你好 -print

我看到你已经解决了这个问题,但这可能对未来有帮助!

于 2014-04-12T11:03:23.573 回答