Ошибка сегментации при использовании функции рекурсии - PullRequest
1 голос
/ 12 февраля 2020

Я довольно новичок в программировании, и для моего класса Object Oriented (в C ++) у нас есть двумерный массив со случайными группировками "X". Я должен использовать рекурсивную функцию, чтобы найти различные группировки и очистить их. На данный момент я проверяю, является ли точка X, очищаю ее, затем проверяю 8 позиций вокруг нее (включая диагонали), и, если одна из позиций в X, я вызываю функцию снова, но в этом месте. Моя идея состоит в том, что, если я найду один X, я смогу собрать все X вокруг него в одном go, таким образом, я смогу считать его группой, когда найду 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 

1 Ответ

1 голос
/ 12 февраля 2020

Давайте играть в компьютер и go через движения для 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 обращения будут go вне памяти, определенной 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.

...