Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 分段故障(堆芯转储)-向量_C++_Segmentation Fault_Stdvector_Coredump - Fatal编程技术网

C++ 分段故障(堆芯转储)-向量

C++ 分段故障(堆芯转储)-向量,c++,segmentation-fault,stdvector,coredump,C++,Segmentation Fault,Stdvector,Coredump,我正在研究一种算法,它可以使用基本线段计算曲线的长度。所以若我有曲线的x和y坐标向量,我需要计算这些基本线段的数量。我发明了自己的递归算法。有一个代码: #include <iostream> #include <vector> #include <cmath> using namespace std; //*********************************************** inline double Pitagoras(doub

我正在研究一种算法,它可以使用基本线段计算曲线的长度。所以若我有曲线的x和y坐标向量,我需要计算这些基本线段的数量。我发明了自己的递归算法。有一个代码:

#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;
}
#包括
#包括
#包括
使用名称空间std;
//***********************************************
内联双皮塔戈拉(双xp、双yp、双xf、双yf)
{
返回sqrt((xp-xf)*(xp-xf)+(yp-yf)*(yp-yf));
}
//***************************************************
内联双计算器(双xp、双yp、双a、双b、常数双eps)
{
双三角洲;
双x1,x2;
增量=(-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(增量))/(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));
如果(x1>=xp)
返回x1;
其他的
返回x2;
}
//***************************************************
内联双计算器(双x、双a、双b)
{
返回a*x+b;
}
//***********************************************
无符号长算法Kolmogorow(双xp,双yp,双xf,
双yf、常数双eps、向量和向量TORX、向量和向量);
//***********************************************
int main()
{
vector vCtrl;//函数值的向量
向量vctrX;//x的向量
double xP,yP,xF,yF;//曲线上两点的坐标
const double Eps=0.0001;//基本线的长度
对于(双x=1.0;x
i++);
xf=vectorX[i];
yf=向量[i];

//cout由于递归,可能正在耗尽堆栈空间

解决这个问题的一个快速方法是在shell中使用
ulimit
,例如

(ulimit -s unlimited; ./my_program)
然而,真正的解决办法是删除递归。
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;
           }

    }

}
无符号长算法Kolmogorow(双xp、双yp、双xf、,
双yf、常数双eps、向量和向量(Torx、向量和向量)
{
静态无符号长N;//licznik
静态无符号长i=1;
双d;
双a,b;
while(true){
d=皮塔戈拉(xp、yp、xf、yf);
如果(d>=eps){
a=(yf-yp)/(xf-xp);
b=yp-a*xp;
xp=calculateX(xp,yp,a,b,eps);
yp=计算(xp,a,b);
N++;
}
否则{
i++;
如果(i>=vectorX.size())
返回N;
xf=vectorX[i];
yf=向量[i];

//cout您的
Eps
值太小。这会导致算法进展太慢,这意味着您在计算完成之前用完了堆栈空间。我将
Eps
增加到0.005,代码运行正常。但不确定它是否生成正确答案;您必须检查

此外,您还需要更改以下行:

xf = vectorX[i];
yf = vectorY[i];
为此:

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

否则,您将访问上一次迭代中的最后一个向量元素。您可能还希望对
Eps
进行公差研究,以了解它必须有多小才能得到准确的计算。

您从未访问
vectorX
vectorY
的第一个或第二个元素。这是故意的吗?请注意
xf=vectorX[一]
将始终尝试访问第三个元素,因为
i
1
开始。请记住,向量是0索引的。当我运行此操作时,
algorithmKolmogorow
中的静态变量
i
永远不会递增,因此末尾的
if
块总是计算为true,并导致无限递归ain函数我为变量xP和xF设置了vectorX[0]和vectorX[1]。我从值I=2开始,因为在您使用的代码之前,增量I++与手头的问题无关,但是您可以使用
std::hypot(xP-xF,yp-yf)
而不是手动计算这些平方和的平方根。现在,我从://cout中删除注释。这也是因为堆栈空间不足。您的算法会导致大量递归,这在堆栈上留下的空间非常小。正如@ex bart指出的,您确实需要o考虑到您对
algorithmKolmogorow
进行的函数调用的数量,消除递归。好的,当我们设置while循环时,它确实可以工作,但我不明白为什么N和I不能是静态的?如果有静态的,程序可以正常工作。@RafałApriasz尝试连续使用
algorithmKolmogorow
两次,使用不同的输入数据。例如,使用
vctrY.push_back(0.5*x*x);//f(x)=(x^2)/2
第二次初始化(不要忘记
vctrX.clear();vctrY.clear();
删除旧值)。如果您注释掉
algorithmKolmogorow
的第一次调用,则新输入数据的值约为12.7508。如果您注释回第一次调用,则该值为24.3852(与原来一样),但第二次调用的值为24.3866,而不是12.7508。
xf = vectorX[i-1];
yf = vectorY[i-1];