Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.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_Cubic Spline - Fatal编程技术网

C 此已发布的三次样条极值代码是否有错误?

C 此已发布的三次样条极值代码是否有错误?,c,cubic-spline,C,Cubic Spline,我正试图实施1996年公布的《公约》 我不是一个有造诣的程序员,作者显然是,而且比我聪明一两个数量级。然而,当我尝试编译这个程序时,它会在一个简单的越界数组访问上出现错误。我发现很难相信这个算法是在我看来是一个小错误的情况下发布的。因此,我认为误解可能是我的,而不是作者。(例如,可能他使用了一个我不知道的技巧,20年前可能在c中工作过…) 第一个SEGFULT发生在此处,试图访问diag[-1]: float *diag; /* ptr to matrix diagonal array

我正试图实施1996年公布的《公约》

我不是一个有造诣的程序员,作者显然是,而且比我聪明一两个数量级。然而,当我尝试编译这个程序时,它会在一个简单的越界数组访问上出现错误。我发现很难相信这个算法是在我看来是一个小错误的情况下发布的。因此,我认为误解可能是我的,而不是作者。(例如,可能他使用了一个我不知道的技巧,20年前可能在c中工作过…)

第一个SEGFULT发生在此处,试图访问
diag[-1]

float *diag;      /* ptr to matrix diagonal array */
for (i = 0; i < num_pnts - 1; i++){
    diag[i-1] = x[i+1] - x[i];
    assert(diag[i-1] > 0);}

所以我的问题是,这个算法是由一个非常有成就的人发布的,而不是CS一年级的学生。所以,虽然这些在我看来像是错误(事实上,2019年系统上的SEGFULT),但我是否还遗漏了其他一些东西?e、 这个OOB错误在1996年的c编译器上会有不同的结果吗


问题:这些真的是错误吗?

是的,这些是实际的错误。使用
malloc()
分配数组
diag
。指针指向所分配区域的开始。当
i
等于
0
时,通过计算
diag[i-1]
,它可以访问所分配数组的边界之外

正如您正确尝试的那样,这段代码的for循环从1开始。事实上,那么
diag[i-2]
也是错误的。由于
main_diag[]
数组是从索引
0
开始填充的,因此我认为这也是次要对角线的目的。所以我认为第二个和第三个循环应该是:

for (i = 0; i < num_pnts - 1; i++) {
  diag[i] = x[i + 1] - x[i];
  assert(diag[i] > 0);
}

/* compute right hand side of equation */
for (i = 1; i < num_pnts - 1; i++) {
  right[i - 1] = 6.0 * ((y[i + 1] - y[i]) / diag[i] - (y[i] - y[i - 1]) / diag[i - 1]);
}
for(i=0;i0);
}
/*计算方程的右侧*/
对于(i=1;i
越界访问不一定会导致分段错误,它只是一种未定义的行为。它取决于编译器和
malloc()
的实现,取决于所分配内存边界之外的内存是否有效。即使内存是可访问的,
diag[i-2]
位于除法运算符的右侧,因此如果该位置的内存包含一个零,它将导致被零除法。因此,它也可能与1999年的编译器一起崩溃


如果您能够找出应该实现哪些公式,然后检查代码是否正确,那将是最好的。

在出现6个完全错误和高度可疑的代码位(即使是90年代中期)后,我停止了计算。我不会用这个例子来说明如何写C。谢谢,你的评论和第二眼。奇怪的是,这本书似乎写得这么好,表达得这么好!我想我会选择统一的
(I=1;I
作为循环控件。谢谢。这样一个(显然)经过深思熟虑、记录良好的算法会伴随着如此糟糕的编码,这看起来确实很奇怪。每个人都会犯错误,即使是比你我聪明两个数量级的人。编码风格现在总体上看起来很糟糕,但在90年代后期非常典型。这是你会在广泛出版的书籍中找到的,比如。非常浓缩。再加上20年前编译器没有那么严格的事实,它实际上可能已经在作者的计算机上运行并产生了合理的结果。
for (i = 0; i < num_pnts - 1; i++) {
  diag[i] = x[i + 1] - x[i];
  assert(diag[i] > 0);
}

/* compute right hand side of equation */
for (i = 1; i < num_pnts - 1; i++) {
  right[i - 1] = 6.0 * ((y[i + 1] - y[i]) / diag[i] - (y[i] - y[i - 1]) / diag[i - 1]);
}