【问题标题】:Segfaulting while finding path through maze在迷宫中寻找路径时出现段错误
【发布时间】:2014-06-08 23:31:46
【问题描述】:

当我尝试使用深度优先搜索算法解决问题时,我正在尝试打印出迷宫的坐标,但是,它会打印出初始位置,但会出现故障。有什么我做错了吗???这是我的代码:

#include "mazegen.h"
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define  BUFFERSIZE 500
#define  FLAG 

void mazeSolution(char maze[100][100], int counter, int counter2)
{
   stack*currentCell;

   int i;
   int j;

   currentCell = create();

  for(i=0; i<counter; i++)
  {
      for(j=0; j<counter2; j++)
      {

          if(maze[i][j] == 'S')
          {
              push(currentCell,i,j);
              currentCell->visited = true;
          }

      }
  }

   printStack(currentCell);

   while(currentCell != NULL)
   { 
      pop(currentCell);

      if(maze[i][j] == 'F')
      {
           break;
      }
      if(i != 0)
      { 
          if(maze[i-1][j] == ' ' && currentCell->visited != true)
          {
              currentCell->visited = true;
              push(currentCell,i-1,j);

          }
      }
      if(maze[i+1][j] == ' ' && currentCell->visited != true)
      {
          currentCell->visited = true;
          push(currentCell,i+1,j);
      }
      if(j != 0)
      {
          if(maze[i][j-1] == ' ' && currentCell->visited != true)
          {
              currentCell->visited = true;
              push(currentCell, i,j-1);
          }
      }
      if(maze[i][j+1] == ' ' && currentCell->visited != true)
      {
           currentCell->visited = true;
            push(currentCell, i, j+1); 
      }

 }

  printf("No solution\n");


  printStack(currentCell);

}

我认为这与我的 pop 功能以及我实现它的方式有关

void pop (stack*theStack)
{
    node*theHead;

    if(theStack == NULL)
    {
        printf("Empty Stack. Error\n");
         exit(0);
    }

    theHead = removeFromFront(theStack->list);

    theStack->list = theHead;


}
node*removeFromFront(node*theList) 
{
    node*temp;

    temp = theList->next;

    if(temp == NULL)
    {
        printf("pop Error\n");
        return NULL;
    }

    theList = theList->next;

    return theList;
}.       

【问题讨论】:

  • 你调试过你的代码吗?它在哪一行产生段错误?
  • 我已经注释掉了 if 语句,所以它会打印出第一个节点,然后它会出现一个错误,然后它会立即出现 sefgaults
  • 向我们展示pop函数的代码
  • 你似乎从不检查 i+1 或 j+1 是否有效?
  • 您定义了BUFFERSIZE,但没有显示它的用途。您认为问题出在 pop 函数中,但您没有显示其实现。您如何想象我们会帮助您,我们会猜出您的整个代码吗?顺便说一句,迷宫大小 100 x 100 会产生 2,500 到 10000 个细胞,具体取决于迷宫的表示形式。您确定 500 项缓冲区就足够了吗?

标签: c maze


【解决方案1】:

看看你的这部分代码:

while(currentCell != NULL)
{ 
      pop(currentCell);

      if(maze[i][j] == 'F')
      {
           break;
      }
   ...
}

您正在从堆栈中弹出一个值 - 这没关系。但是您需要将弹出的值分配给i 和j。在您的代码中,i 和 j 的值保持不变,因此您有一个无限的 while 循环。您在此循环内不断地向堆栈中推送值,这最终会导致段错误。

【讨论】:

  • 哦,我明白你的意思了。我将如何分配它??
  • @user3712556 修改您的pop 函数,以便它分配i 和j 位于堆栈顶部的值。一种可能的解决方案是将i 和j 作为弹出函数(void pop (stack* theStack, int* i, int* j))的参数传递。
  • 我试过了,它不起作用,它仍然是段错误。这就是我所做的。 void pop (stacktheStack, int x, int y) { 节点theHead; if(theStack == NULL) { printf("空栈。错误\n");退出(0); } theHead = removeFromFront(theStack->list, x, y); theStack->list = theHead; }
  • 1.您需要将i 和j 分配给它们的适当值(这是堆栈的顶部值) 2. 您需要通过引用而不是通过值来传递它们
  • 我不明白的是,如果我们弹出迷宫的第一个位置,堆栈中将没有任何内容,这就是它出现段错误的原因。网上看到这个逻辑,应用了,但是第一个节点的pop好像没理解好?
【解决方案2】:

在堆栈上保持 visited 状态是没有用的 - 当您尝试从某个新方向访问特定位置时,您需要检查是否已访问特定位置,如果存在循环,则可能会发生这种情况在你的迷宫里。所以这个属性的合适位置是迷宫本身,而不是堆栈。

您不需要单独的 stack 和 node 结构 - 堆栈实际上是一个节点列表。

构建堆栈非常简单,但您需要在开始编码之前想象它的结构和行为。有两种基本(纯 C)解决方案:使用预分配数组或动态链表。让我们使用一个数组。

堆栈的项目将是

typedef struct node {
    int i, j;
} Node;

堆栈本身:

Node stack[ 10001];

以及当前堆叠的物品数量:

int stkptr = 0;

现在我们可以测试堆栈是否包含任何数据:

int StackNonEmpty() { return stkptr; }

将新位置压入堆栈:

void Push(int i, int j) {
    stack[ stkptr].i = i;
    stack[ stkptr].j = j;
    stkptr ++;
}

从栈顶读取一个位置(假设StackNonEmpty() != 0):

void Fetch(int *pi, int *pj) {
    *pi = stack[ stkptr - 1].i;
    *pj = stack[ stkptr - 1].j;
}

并将其从堆栈中移除:

void Pop() { stkptr --; }

我们还需要为访问过的位置定义一个标记:

int VISITED = '.';

或

#define VISITED '.'

我们已经准备好编写算法了:

for(i=0; i<counter; i++)
    for(j=0; j<counter2; j++)
        if(maze[i][j] == 'S')
        {
            Push(i,j);   // set the Start position
            i = counter; // this is to break the outer loop
            break;       // and this breaks the inner loop
        }
while( StackNonEmpty())
{
    Fetch(& i, & j);             // get a current position
    if( maze[i,j] == 'F')              // Finish found?
        break;
    if( maze[i,j] == ' ')              // empty cell?
        maze[i,j] = VISITED;
    // find next possible step
    if( i > 0 && maze[i-1,j] == ' ')   // cell to the left is empty
        Push(i-1,j);                   // step left
    else
    if( j > 0 && maze[i,j-1] == ' ')   // cell above is empty
        Push(i,j-1);                   // step up
    else
    if( i+1 < counter && maze[i+1,j] == ' ')
        Push(i+1,j);                   // step right
    else
    if( j+1 < counter2 && maze[i,j+1] == ' ')
        Push(i,j+1);                   // step down
    else                               // dead end - no way out
        Pop();                         // step back
}
if( StackNonEmpty())      // exited with break, so 'F' found
    PrintStack();
else
    PrintFailureMessage();  // could not reach 'F'

要显示结果,只需打印 stack 数组的所有项目,直到 stkptr 位置:

void PrintStack() {
    for(i = 0; i < stkptr; i ++)
        printf( "%d,%d\n", stack[i].i, stack[i].j);
}

编辑
'VALID' 状态分配已更正(是 == 而不是 =),PrintFailureError 替换为 PrintFailureMessage。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多