【问题标题】:Segmentation fault when using recursion function使用递归函数时出现分段错误
【发布时间】:2020-05-28 03:50:55
【问题描述】:

我对编程很陌生,对于我的面向对象类(在 C++ 中),我们有一个带有“X”随机分组的二维数组。我必须使用递归函数来查找不同的分组并清除它们。截至目前,我检查该点是否是 X,清除它,然后检查它周围的 8 个位置(包括对角线),如果 X 中的一个位置,我再次调用该函数,但在那个位置。我的想法是,如果我找到一个X,我将能够一次将它周围的所有X都搞定,因此,当我找到一个X时,我可以将它算作一个组。

在函数结束时,我基本上循环遍历所有点,如果有另一个 X,则再次调用递归函数。但是,我不断收到分段错误,我不知道为什么。任何帮助将不胜感激!


void  Recurssive(string Array[][72],int Pos1, int Pos2)
{

int One=1;
int Two=1;
//cout<<"Test 2";
if(Array[Pos1][Pos2]=="X")
        {
        Array[Pos1][Pos2]="0";
        if(Array[Pos1+1][Pos2]=="X")
                {
                Recurssive(Array,Pos1+1,Pos2);
                }
         if(Array[Pos1-1][Pos2]=="X")
                {
                Recurssive(Array,Pos1-1,Pos2);
                }
         if(Array[Pos1][Pos2+1]=="X")
                {
                Recurssive(Array,Pos1,Pos2+1);
                }
         if(Array[Pos1][Pos2-1]=="X")
                {
                Recurssive(Array,Pos1,Pos2-1);
                }
         if(Array[Pos1+1][Pos2+1]=="X")
                {
                Recurssive(Array,Pos1+1,Pos2+1);
                }
         if(Array[Pos1-1][Pos2-1]=="X")
                {
                Recurssive(Array,Pos1-1,Pos2-1);
                }
         if(Array[Pos1+1][Pos2-1]=="X")
                {
                Recurssive(Array,Pos1+1,Pos2-1);
                }
         if(Array[Pos1-1][Pos2+1]=="X")
                {
                Recurssive(Array,Pos1-1,Pos2+1);
                }

        }

for(int i=1;i<22;i++)
        {
        for(int j=1;j<72;j++)
                {
                if(Array[i][j]=="X")
                        {
                        Recurssive(Array,i,j);
                        }
                }
        }


}

这是我循环的数组的输出

            X                                                         
             X                                                        
              X           XXXXXXXXXXXXXXX                             
               X          XXXXXXXXXXXXXXX                             
                X         XXXXXXXXXXXXXXX        XXXX                 
                 XXXX     XXXXXXXXXXXXXXX      XXX  XXX               
                     X                        XXX    XXX              
     XXXXXXXXXXXXXX   X                      XXX      XXX             
     XX          XX    X                      XXX    XXX              
     XX          XX     X                      XXX  XXX               
     XX          XX      X                       XXXX                 
     XX  XXXXX   XX       X                                           
     XX          XX        X                                          
     XX          XX         X                                         
     XXXXXXXXXXXXXX          X                                        
                                          X                           
                                         X                            
                                        X                             
                                       X                              
                                      X 

【问题讨论】:

  • 这听起来像是一个很好的了解调试器的练习。它将允许您单步执行代码并弄清楚会发生什么。我建议在只有两个标有 X 的位置的空板上试一试。
  • 您的for 允许j 最多为71,而在Recurssive 函数中可以使用j+1 调用它(因此超出了数组的范围)。 i也是一样的
  • j = 71 时,您正在访问72nd 索引在f(Array[Pos1][Pos2+1]=="X"),这是越界访问,因为数组是从0 开始的。不知道,由于缺少 minimal reproducible example (因此 - 不知道数组的两个维度),i 索引是否可以这样说,但怀疑它有同样的问题。
  • @Hawky "i 是一样的" 从技术上讲 - 不能确定 i 是一样的,因为这个维度问题中未显示数组的。只能猜测,这可能是一个问题。
  • 感谢您的 cmets!我将循环转到 21 和 71,但是它仍然抛出相同的错误?

标签: c++ recursion segmentation-fault


【解决方案1】:

让我们玩电脑,为Recurssive(Array, 0, 0) 做动作。 如果这个位置被标记为X,这将按顺序进行以下数组访问:

Array[1][0]
Array[-1][0]
Array[0][1]
Array[0][-1]
Array[1][1]
Array[-1][-1]
Array[1][-1]
Array[-1][1]

这些-1 访问将超出Array 定义的内存,并可能读取随机值或可能导致分段错误。

为了解决这个问题,您需要在实际访问之前验证候选职位是否在董事会内。 比如:

std::optional<std::string> safe_access(std::string Array[][72], int Pos1, int Pos2) {
  if (Pos1 < 0 || Pos1 >= 71) return {};
  if (Pos2 < 0 || Pos1 >= 21) return {};
  return Array[Pos1][Pos2];
}

然后您可以致电safe_access(Array, -1, -1) == "X" 并保证不会在Array 之外访问。

【讨论】:

  • 是的,就是这样!非常感谢!
猜你喜欢
  • 2021-02-25
  • 2020-03-22
  • 2018-09-10
  • 2014-11-05
  • 2017-04-06
  • 2020-04-20
  • 2017-11-12
  • 2016-11-06
相关资源
最近更新 更多