C 递归函数中的分段错误

C 递归函数中的分段错误,c,segmentation-fault,C,Segmentation Fault,我正在执行任务的一部分。我已经正确地编码了它,但我不知道它为什么会出现分段错误。 我将strassen()称为strassen(0,n,0,n)在主菜单中。n是用户给定的二次幂数,是矩阵(2D数组)的最大大小。 对于n=4,它没有给出SEGFULT,但是对于n=8,16,32,它给出了SEGFULT。 代码如下所示 void strassen(int p, int q, int r, int s) { int p1,p2,p3,p4,p5,p6,p7;

我正在执行任务的一部分。我已经正确地编码了它,但我不知道它为什么会出现分段错误。 我将strassen()称为strassen(0,n,0,n)在主菜单中。n是用户给定的二次幂数,是矩阵(2D数组)的最大大小。 对于n=4,它没有给出SEGFULT,但是对于n=8,16,32,它给出了SEGFULT。 代码如下所示

    void strassen(int p, int q, int r, int s)
    {
        int p1,p2,p3,p4,p5,p6,p7;   
        if(((q-p) == 2)&&((s-r) == 2))
        {
            p1 = ((a[p][r] + a[p+1][r+1])*(b[p][r] + b[p+1][r+1]));
            p2 = ((a[p+1][r] + a[p+1][r+1])*b[p][r]);
            p3 = (a[p][r]*(b[p][r+1] - b[p+1][r+1]));
            p4 = (a[p+1][r+1]*(b[p+1][r] - b[p][r]));
            p5 = ((a[p][r] + a[p][r+1])*b[p+1][r+1]);
            p6 = ((a[p+1][r] - a[p][r])*(b[p][r] +b[p][r+1]));
            p7 = ((a[p][r+1] - a[p+1][r+1])*(b[p+1][r] + b[p+1][r+1]));
            c[p][r] = p1 + p4 - p5 + p7;
            c[p][r+1] = p3 + p5;
            c[p+1][r] = p2 + p4;
            c[p+1][r+1] = p1 + p3 - p2 + p6;
        }
        else
        {
            strassen(p, q/2, r, s/2);
            strassen(p, q/2, s/2, s);
            strassen(q/2, q, r, s/2);
            strassen(q/2, q, s/2, s);
        }
    }

else块中的某些条件是无限递归的(至少第二个和第四个条件没有选中另一个)。这可以用纸和笔很容易地证明: e、 g.
strassen(p,q/2,s/2,s)
0,8,0,8在每次迭代中都会产生:

1) 0, 4, 4, 8

2) 0, 2, 4, 8

3) 0, 1, 4, 8

4) 0, 0, 4, 8

5) 0, 0, 4, 8

既然这些结果都没有通过你的测试

if(((q-p) == 2)&&((s-r) == 2))
测试时,函数将运行(我怀疑是分支,因为第四个函数也有同样的问题…)直到堆栈的末尾被击中,从而导致分段错误

无论如何,如果您在else块中尝试做的是递归对分矩阵,那么更好的尝试是:

strassen(p, (q+p)/2, r, (r+s)/2);                                               
strassen(p, (q+p)/2, (r+s)/2, s);                                               
strassen((q+p)/2,q, (r+s)/2, s);                                                
strassen((q+p)/2,q, r, (r+s)/2);        
(请记住,我没有检查此代码)

但是在函数的开头会有一个更简单的递归止点,如:

{
    int p1,p2,p3,p4,p5,p6,p7;   
    if(q-p < 2 || s-r < 2) return;
    if(q-p == 2 && s-r == 2)
    { ...
{
int p1,p2,p3,p4,p5,p6,p7;
如果(q-p<2 | | s-r<2)返回;
如果(q-p==2&&s-r==2)
{ ...

最有可能的情况是终止条件不正确,函数递归直到溢出堆栈。您至少应该检查在调试器中运行时发生的情况。如果调试器在
c
数组的某个赋值处停止,请检查索引,使其不超出边界。不要让我们猜测。原因是什么segfault的e,堆栈溢出或超出数组边界?在gdb中对其进行打击并提供更多信息。您也可以尝试将
int
声明放置在第一个
if
中。尽管我认为Joachim是正确的。您确定条件是
=
而不是
吗?我将首先删除不需要的p如果
if(q-p<2&&s-r<2),递归不会停止<代码> >代码> < <代码> >代码> b>代码>和<代码> c>代码>来自哪里?我猜它们是全局的,参数是数组的维数。请考虑编辑你的问题来澄清这个问题。不是每个人都熟悉施特拉森的矩阵乘法算法。提供一个链接会很有帮助。谢谢,我是WI。I’我会再次尝试用钢笔、纸和gdb检查它。如果我的答案满足您的问题,请不要忘记将其标记为解决方案;-)
{
    int p1,p2,p3,p4,p5,p6,p7;   
    if(q-p < 2 || s-r < 2) return;
    if(q-p == 2 && s-r == 2)
    { ...