简体   繁体   English

Segmentation Fault(Core Dumped)-矢量图

[英]Segmentation Fault (core dumped) - vectors

I am working at algorithm which can calculate length of curve using elementary segments. 我正在使用可以使用基本线段计算曲线长度的算法。 So if I have vector of x and y coordinates of curve I need to calculate number of this elementary segments. 因此,如果我有曲线的x和y坐标矢量,则需要计算此基本段的数量。 I've invented my own recursive algorithm for that. 为此,我发明了自己的递归算法。 There is a code: 有一个代码:

#include <iostream>
#include <vector>
#include <cmath>

using namespace std;
//***********************************************
inline double Pitagoras(double xp, double yp, double xf, double yf)
{
    return sqrt((xp - xf)*(xp - xf) + (yp - yf)*(yp - yf));
}
//***************************************************
inline double calculateX(double xp, double yp, double a, double b, const double eps)
{
   double delta;
   double x1, x2;

     delta = (-2.0 * xp + 2.0 *a*b - 2.0 *a*yp)*(-2.0 * xp + 2.0 *a*b - 2.0 *a*yp)
        - 4.0* (1.0 + a*a)*(xp*xp + yp*yp + b*b - 2.0*b*yp - eps*eps);

     x1 = (-(-2.0 * xp + 2.0 *a*b - 2.0 *a*yp) - sqrt(delta))/(2.0 * (1.0 + a*a));
     x2 = (-(-2.0 * xp + 2.0 *a*b - 2.0 *a*yp) + sqrt(delta))/(2.0 * (1.0 + a*a));

   if(x1 >= xp)
     return x1;
     else
       return x2;
}
//***************************************************
inline double calculateY(double x, double a, double b)
{
  return a*x + b;
}
//***********************************************
unsigned long algorithmKolmogorow(double xp, double yp, double xf,
double yf, const double eps, vector<double> &vectorX, vector<double> &vectorY);
//***********************************************
int main()
{
    vector<double> vctrY; //vector of value of function
    vector<double> vctrX; //vector of x
    double xP,yP,xF,yF; //coordinates of two points on the curve
    const double Eps = 0.0001; //length of elementary line

      for(double x=1.0; x<=5 ;x +=0.001)
        {
          vctrX.push_back(x);
          vctrY.push_back(x*x); //f(x) = x^2
        }

    xP = vctrX[0];
    yP = vctrY[0];
    xF = vctrX[1];
    yF = vctrY[1]; //set beginning value

    cout<<algorithmKolmogorow(xP, yP, xF, yF, Eps, vctrX, vctrY)*Eps;

    return 0;
}
//***************************************************
unsigned long algorithmKolmogorow(double xp, double yp, double xf,
 double yf, const double eps, vector<double> &vectorX, vector<double> &vectorY)
{
    static unsigned long N; //licznik
    static unsigned long i = 1;
    double d;
    double a,b;

      d = Pitagoras(xp, yp, xf, yf);

         if(d >= eps){
            a = (yf - yp)/(xf - xp);
            b = yp - a*xp;
            xp = calculateX(xp, yp, a, b, eps);
            yp = calculateY(xp, a, b);
            N++;
         }

           else{
             i++;
             xf = vectorX[i];
             yf = vectorY[i];
             //cout<<i<<"\t"<<vectorX[i]<<"\t"<<vectorY[i]<<endl;
           }

             if(i < vectorX.size())
              N =  algorithmKolmogorow(xp, yp, xf, yf, eps, vectorX, vectorY);

return N;
}

In main as you can see, I'm setting x,y coordinates for parabolic function. 如您所见,主要是为抛物线函数设置x,y坐标。 When Eps is big for example Eps = 0.001 everything works. 例如,当Eps大时,Eps = 0.001,则一切正常。 If I set smaller value like Eps = 0.0001 then I get error like in topic and program stop running. 如果我设置较小的值(例如Eps = 0.0001),则会出现类似主题的错误,程序将停止运行。 I've completely no idea why. 我完全不知道为什么。

I can add any new informations which you need (about my compiler, IDE, OS etc). 我可以添加您需要的任何新信息(关于我的编译器,IDE,OS等)。

Rafal 拉法尔

         i++;
         xf = vectorX[i];
         yf = vectorY[i];
         //cout<<i<<"\t"<<vectorX[i]<<"\t"<<vectorY[i]<<endl;
       }

         if(i < vectorX.size())

That will exceed the bounds of the vector by 1. Maybe you needed if(i < vectorX.size()-1) or (noting the comment by AndyG) maybe you needed the i++ to be below those two uses of i . 那将超出向量的边界1。也许您需要if(i < vectorX.size()-1)或(请注意AndyG的评论)也许您需要i++低于i这两种用法。

You are probably running out of stack space due to the recursion. 由于递归,您可能用完了堆栈空间。

A quick hack around this is to raise the stack size using ulimit in the shell, eg 一个快速的解决方法是在外壳中使用ulimit提高堆栈大小,例如

(ulimit -s unlimited; ./my_program)

The real fix however is to remove the recursion. 但是,真正的解决方法是删除递归。 algorithmKolmogorow looks like it does tail-recursion only, which can always be converted to a loop: algorithmKolmogorow看起来只执行尾递归,它总是可以转换为循环:

unsigned long algorithmKolmogorow(double xp, double yp, double xf,
 double yf, const double eps, vector<double> &vectorX, vector<double> &vectorY)
{
    static unsigned long N; //licznik
    static unsigned long i = 1;
    double d;
    double a,b;

    while(true) {
      d = Pitagoras(xp, yp, xf, yf);

         if(d >= eps){
            a = (yf - yp)/(xf - xp);
            b = yp - a*xp;
            xp = calculateX(xp, yp, a, b, eps);
            yp = calculateY(xp, a, b);
            N++;
         }

           else{
             i++;
             if(i >= vectorX.size())
               return N;
             xf = vectorX[i];
             yf = vectorY[i];
             //cout<<i<<"\t"<<vectorX[i]<<"\t"<<vectorY[i]<<endl;
           }

    }

}

There also fixes the problem of accessing the vectors one element passed their bounds. 这也解决了访问一个元素超过其边界的向量的问题。

There are still some problems: 仍然存在一些问题:

  • N should be initialized N应该初始化
  • algorithmKolmogorow can only be used once per program invocation. 每个程序调用只能使用一次algorithmKolmogorow Remove the static from N and i to fix that. Ni删除static ,以解决此问题。

Your value for Eps is too small. 您的Eps价值太小。 It causes the algorithm to progress too slowly, which means you run out of stack space before the calculation can finish. 这会导致算法进行的速度太慢,这意味着您会在计算完成之前耗尽堆栈空间。 I increased Eps to 0.005 and the code runs fine. 我将Eps增加到0.005,并且代码运行正常。 Not sure if it produces the right answer though; 不确定是否会产生正确的答案; you'll have to check. 您必须检查一下。

Also, you need to change these lines: 另外,您需要更改以下行:

xf = vectorX[i];
yf = vectorY[i];

To this: 对此:

xf = vectorX[i-1];
yf = vectorY[i-1];

Otherwise you access past the last vector element on the last iteration. 否则,您将访问最后一次迭代中的最后一个向量元素。 You may also want to do a tolerance study on Eps to see how small it has to be to get an accurate calculation. 您可能还需要对Eps进行公差研究,以查看获得准确计算所需要的尺寸。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM