C program : Maze shortest path

ralbhat

Disciple
Hey,

I've made a program to find the shortest path in a maze.. doesn't work though. Gives the weirdest error (NEVER seen this one before) on linux.. haven't tested it on windows. Help me!:

Code:
// Maze is :

//

//   __________

//  |O|X|X|  |  |  |

//  |   |  |  |  |X|  |

//  |   |  |  |X|X|  |

//  |   |  |  |X|X|  |

//  |   |X|X|X|X|  |

//  |_ |_ |_| _|_|W|

//

//  where X means that passing is not possible, and blank means passing is possible. O is the starting point,

//  and W is the Final position The shortest path solution for this maze would, hence, be :

//  0,0

//  0,1

//  0,2

//  0,3

//  0,4

//  0,5

//  1,5

//  2,5

//  3,5

//  4,5

//  5,5

//  The top-left corner is 0,0 and the bottom right is 5,5 in numbering.

#include<stdio.h>

int maze[6][6] = {{0,1,1,0,0,0},{0,0,0,0,1,0},{0,0,0,1,1,0},{0,0,0,1,1,0},{0,1,1,1,1,0},{0,0,0,0,0,0}};

int start[2] = {0,0},end[2]={5,5};

typedef struct n{

  int i,j;

  int *history;

  int lenh;

} node;

typedef struct s{

  node *n;

  struct s *next,*prev;

}list;

node *ans = NULL;

list *stack = NULL;

list *ltop;

int found = 0;

void push(node *new);

list *move(list *start);

int isinhistory(int history[],int len,int tofind[2]);

int isfinal(node *candidate);

//void view();

int main(void){

  int i;

  list *lstart;

  node *abc = (node*)malloc(sizeof(node));

  abc->i = start[0];

  abc->j = start[1];

  abc->history = NULL;

  abc->lenh=0;

  stack = (list *)malloc(sizeof(list));

  stack->next = NULL;

  stack->n = abc;

  lstart=stack;

  ltop = stack;

  while(!found) lstart = move(lstart);

  if (found == 1)

    for(i=0;i<(ans->lenh);i++)

     printf("%d,%d\n",ans->history[2*i],ans->history[2*i+1]);

  else if (found == -1)

    printf("No route!");

}

// ----------- isfinal

int isfinal(node *candidate){

  if(candidate->i == end[0])

    if(candidate->j == end[1])

      return 1;

  return 0;

}

// ----------- isinhistory

int isinhistory(int history[],int len,int tofind[2]){

  int i;

  for(i = 0;i<len;i++)

    if(tofind[0] == history[2*i] && tofind[1]==history[2*i+1]) return 1;

  return 0;

}

// ---------- push

void push(node *new){

  list *top = (list *)malloc(sizeof(list));

  top->n=new;

  top->next=ltop;

  top->prev = NULL;

  ltop->prev = top;

  ltop=top;

}

// ---------- move

list *move(list *start){

//  printf("reached move");

  int left[]={(start->n->i)-1,start->n->j},right[]={(start->n->i)+1,start->n->j};

  int up[]={start->n->i,(start->n->j)-1},down[] = {start->n->i,(start->n->j)+1};

  int i;

  node *new = (node *)malloc(sizeof(node));

//  printf("1");

  if((start->n->i)-1>0 && !(isinhistory(start->n->history,start->n->lenh,left))){

    new->i = (start->n->i)-1;

    new->j = (start->n->j);

    new->history = (int *)malloc(2*(start->n->lenh+1));

    new->lenh = (start->n->lenh)+1;

    for(i=0;i<(start->n->lenh);i++){

	new->history[2*i] = start->n->history[2*i];

	new->history[2*i+1] = start->n->history[2*i+1];

    }

    new->history[2*i] = start->n->i;

    new->history[2*i+1] = start->n->j;

    if(isfinal(new)){

      found = 1 ;

      ans= new;

    }

    else push(new);

  }

//  printf("2");

  if((start->n->i)+1<6 && !(isinhistory(start->n->history,start->n->lenh,right))){

    new->i = start->n->i+1;

    new->j = start->n->j;

    new->history = (int *)malloc(2*(start->n->lenh+1));

    new->lenh = (start->n->lenh)+1;

    for(i=0;i<(start->n->lenh);i++){

        new->history[2*i] = start->n->history[2*i];

        new->history[2*i+1] = start->n->history[2*i+1];

    }

    new->history[2*i] = start->n->i;

    new->history[2*i+1] = start->n->j;

    if(isfinal(new)){

      found=1 ;

      ans= new;

    }

    else push(new);

  }

//  printf("3");

  if((start->n->j)-1>0 && !(isinhistory(start->n->history,start->n->lenh,up))){

    new->i = start->n->i;

    new->j = start->n->j-1;

    new->history = (int *)malloc(2*(start->n->lenh+1));

    new->lenh = (start->n->lenh)+1;

    for(i=0;i<(start->n->lenh);i++){

        new->history[2*i] = start->n->history[2*i];

        new->history[2*i+1] = start->n->history[2*i+1];

    }

    new->history[2*i] = start->n->i;

    new->history[2*i+1] = start->n->j;

    if(isfinal(new)){

      found=1 ;

      ans= new;

    }

    else push(new);

  }

//  printf("4");

  if((start->n->j)+1<6 && !(isinhistory(start->n->history,start->n->lenh,down))){

    new->i = start->n->i;

    new->j = start->n->j+1;

    new->history = (int *)malloc(2*(start->n->lenh+1));

    new->lenh = (start->n->lenh)+1;

    for(i=0;i<(start->n->lenh);i++){

        new->history[2*i] = start->n->history[2*i];

        new->history[2*i+1] = start->n->history[2*i+1];

    }

    new->history[2*i] = start->n->i;

    new->history[2*i+1] = start->n->j;

    if(isfinal(new)){

      found =1 ;

      ans= new;

    }

    else push(new);

  }

  if(start==ltop) found = -1;

  list *temp,*top = ltop;

  temp = start;

  start = start->prev;

  start->next = NULL;

  free(temp->n->history);

  free(temp);

//  view();

  return start;

}

// ---- view

/*void view(){

  int dummy;

  list *top = ltop;

  while( top->next !=NULL){

    printf("\n%d\n",top->n->lenh);

    top=top->next;

  }

  scanf("%d",&dummy);

}*/

I've used a stack to keep a list of what I haven't gone through in the maze yet, and the history is used to know what i've already visited. I tried linking my stack both ways, too.

snapshot1eb.jpg


Oh.. there's the image.

HELP!
 
next time u write any program make sure that u make most use of comments, so that it is interpretable what u want from each part. It would also make debugging easier.
 
you should learn using gdb and then run it in the debugger. dont forget to add -g compiler option.

the error is happening because you are sending invalid value to free. you are unable to see the function names because you did not enable -g switch so its unable to find the function symbol information.

Just add -g switch to the compilation and you will see which function is actually faulting.

hope that helps
 
ok.. here's the code i used in the end :

Code:
// The program randomly populates a 6X6 array with 1's and 0's. It then randomly chooses a start point and an

// end point. It then prints the maze, the coordinates of the start and end points, and the path from the start

// point to the end point.

#include<stdio.h>

#include<stdlib.h>

// ------ Define the structure of a node, i.e. the block in the maze that we consider.

typedef struct n{

  int i,j;

  struct n *prev;

} node;

node *ans;

// -------- Define the maze and the start and end points

int maze[6][6];

int start[2],end[2];

int found = 0;

// Randomly generate this information

void populate(){

  int ch,i,j;

  srand(time(NULL));

  for(i = 0; i<6;i++){

    for(j=0;j<6;j++){

      maze[i][j] = rand()%2;

    }

  }

  start[0] = rand()%6;

  start[1] = rand()%6;

  end[0] = rand()%6;

  end[1] = rand()%6;

  maze[start[0]][start[1]] = 0;

  maze[end[0]][end[1]] = 0;

  printf("The start point is: %d,%d\nThe end point is: %d,%d\n",start[0]+1,start[1]+1,end[0]+1,end[1]+1);

}

// For printing the maze :

void printmaze(){

  int i=0,j=0;

  for(i=0;i<6;i++){

    for(j=0;j<6;j++){

      printf("%d   ",maze[i][j]);

    }

  printf("\n");

  }

}

// ------- We will maintain the levels of nodes in a stack; one present and one future level. Define the stack structure.

typedef struct s{

  node *n;

  struct s *next;

} stack;

// ------ The top pointers of the two stacks that we will make.

stack *top_cur,*top_fut;

// ------ Push() for the stack; we will be pushing nodes into the future stack

void push(node *n){

  stack *new = (stack*)malloc(sizeof(stack));

  new->n = n;

  new->next = top_fut;

  top_fut = new;

}

// ----- isfinal() takes a node and checks if it is the final node.

int isfinal(node *n){

  if ( (n->i)==end[0] && (n->j) == end[1] ) return 1;

  return 0;

}

// ----- move() will analyze the surrent stack and will place all possible futures into the future stack. The future stack then becomes the current stack till

// ----- the final position is reached.

void move(){

  int counter=0;

  top_fut = (stack *)malloc(sizeof(stack));

  top_fut->n = NULL;

  top_fut->next = NULL;

  while(top_cur->next!=NULL){

    node *con;

    con = top_cur->n;

    if(isfinal(con)){

      found=1;

      ans = con;

    }

    int left[] = {con->i-1,con->j},right[]={con->i+1,con->j},up[]={con->i,con->j-1},down[]={con->i,con->j+1};

    if(left[0]>=0 && maze[left[0]][left[1]] == 0){

      node *new=(node*)malloc(sizeof(node));

      new->i = left[0];

      new->j = left[1];

      new->prev = con;

      maze[new->i][new->j]=1;

      push(new);

      counter++;

    }

    if(right[0]<=5 && maze[right[0]][right[1]] == 0){

      node *new = (node *)malloc(sizeof(node));

      new->i=right[0];

      new->j=right[1];

      new->prev = con;

      maze[right[0]][right[1]]=1;

      push(new);

      counter++;

    }

    if(up[1]>=0 && maze[up[0]][up[1]] == 0){

      node *new=(node*)malloc(sizeof(node));

      new->i = up[0];

      new->j = up[1];

      new->prev = con;

      maze[new->i][new->j]=1;

      push(new);

      counter++;

    }

    if(down[1]<=5 && maze[down[0]][down[1]] == 0){

      node *new=(node*)malloc(sizeof(node));

      new->i = down[0];

      new->j = down[1];

      new->prev = con;

      maze[new->i][new->j]=1;

      push(new);

      counter++;

    }

    top_cur = top_cur->next;

  }

  top_cur = top_fut;

  if(counter ==0) found = -1;

}

// ----- view() to view generations

void view(){

 if(top_fut->next!=NULL){

  stack *temp = top_fut;

  printf("\n");

  while(temp->next != NULL){

   printf("%d,%d\t",temp->n->i,temp->n->j);

   temp = temp->next;

  } 

  printf("\n\n");

 }

}

int main(void){

  populate();

  printmaze();

  int counter=0;

  top_cur = (stack*)malloc(sizeof(stack));

  top_cur->n = NULL;

  top_cur->next = NULL;

  node *first = (node *)malloc(sizeof(node));

  first->i = start[0];

  first->j = start[1];

  first->prev = NULL;

  maze[start[0]][start[1]] = 1;

  stack *once=(stack *)malloc(sizeof(stack));

  once->n = first;

  once->next = top_cur;

  top_cur = once;

  once = NULL;

  free(once);

  do{

    move();

//    view();

  }while(found == 0);

  

//  printf("%d,%d\n",ans->i,ans->j);

//  printf("%d\n",found);

//  printf("Out of the while loop\n");

  if(found == 1){

    top_fut = (stack *)malloc(sizeof(stack));

    top_fut->next = NULL;

    top_fut->n = NULL;

//    printf("Done allotting\n");

    while(ans->prev!=NULL){

      push(ans);

      ans = ans->prev;

    }

//    printf("Done ans=ans->prev\n");

    printf("Shortest path :\n");

    printf("%d,%d\n",start[0]+1,start[1]+1);

    while(top_fut->next!=NULL){

      printf("%d,%d\n",top_fut->n->i+1,top_fut->n->j+1);

      top_fut = top_fut->next;

    }

//    printf("Answered\n");

  }

  else

    printf("No path found!\n");

  return 0;

}
 
Back
Top