递归回溯迷宫生成器C ++中的分段错误

时间:2016-05-19 15:06:20

标签: c++ recursion

所以我试图使用递归回溯创建一个迷宫生成器,并遇到了一个我无法理解的问题。由于某种原因,我的移动功能返回值" 18446744073709551615"。这(当然)会导致分段错误。当我的移动函数只能将值增加或减少2时,为什么我的移动函数返回如此大的值?

bool maze::generate(size_t x, size_t y) {

//mark the position as visited
labyrinth.s[y][x] = true;

//print to see progress
//this->print();

//if the position is not out of bounds
if (x < 0 || x > labyrinth.MAXWIDTH - 1 || y < 0 || y > labyrinth.MAXHIGHT - 1) {
//if the position is the endpoint return true
if (labyrinth.v[y][x - 1] == 'W' || labyrinth.v[y][x + 1] == 'W' || labyrinth.v[y - 1][x] == 'W' || labyrinth.v[y + 1][x] == 'W') {
  return true;
 }
}

//pick a random direction
do {
  d = size_t(rand() % 4);
} while(!this->pos_test(x, y, d));
std::cout << x << ' ' << y << std::endl;

if (d == UP) {
y = move(x, y, UP);
}
else if (d == DOWN) {
y = move(x, y, DOWN);
}
else if (d == RIGHT) {
x = move(x, y, RIGHT);
}
else if (d == LEFT) {
x = move(x, y, LEFT);
}
else{
}
std::cout << x << ' ' << y << std::endl;
//recursively generate the maze
if (this->generate(x, y)) {
  return true;
}
}

void maze::initialize(size_t x, size_t y) {
   //set the maxhight and the maxwidth to y and x
   labyrinth.MAXHIGHT = y;
   labyrinth.MAXWIDTH = x;
   //set all elements in the vector to #
   for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
     std::vector<char> temp;
     for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
       temp.push_back(labyrinth.wall);
     }
     labyrinth.v.push_back(temp);
   }
   for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
     for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
       if (j % 2 == 1 && i % 2 == 1 && j != labyrinth.MAXWIDTH - 1 && j != 0 && i != labyrinth.MAXHIGHT - 1 && i != 0) {
         labyrinth.v[j][i] = labyrinth.path;
       }
     }
   }
     //set all posistions to unvisited
     for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
       std::vector<bool> temp2;
       for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
         temp2.push_back(false);
       }
       labyrinth.s.push_back(temp2);
    }
     //setup the start point
     labyrinth.v[0][1] = 'S';
     //setup the endpoint
     labyrinth.v[labyrinth.MAXHIGHT - 2][labyrinth.MAXWIDTH - 1] = 'W';

  }

  //if a position has been visited or if not possible to go to return true
 bool maze::pos_test(size_t x, size_t y, size_t d) const {
    //if the position is out of bounds return false
    if (x < 0 || y < 0 || x > labyrinth.MAXWIDTH - 1 || y > labyrinth.MAXHIGHT - 1) {
       return true;
   }
    else if (x == 1 && d == LEFT) {
      return true;
   }
    else if (y == 1 && d == UP) {
      return true;
   }
   else if (x == labyrinth.MAXWIDTH - 1 && d == RIGHT) {
     return true;
   }
   else if (y == labyrinth.MAXHIGHT - 1 && d == DOWN) {
     return true;
   }
   else if (d == UP) {
     return labyrinth.s[y - 2][x];
   }
   else if (d == DOWN) {
     return labyrinth.s[y + 2][x];
   }
   else if (d == RIGHT) {
     return labyrinth.s[y][x + 2];
   }
   else if (d == LEFT) {
     return labyrinth.s[y][x - 2];
   }
   else  {
     return true;
   }
 }


size_t maze::move(size_t x, size_t y, size_t d) {
//if the position is out of bounds return without modifying
if (x < 0 || x > labyrinth.MAXWIDTH - 1) {
  return x;
}
else if (y < 0 || y > labyrinth.MAXHIGHT - 1) {
  return y;
}
else if (d == UP) {
  labyrinth.v[y - 1][x] = labyrinth.path;
  return y =  y - 2;
}
else  if (d == DOWN) {
  labyrinth.v[y + 1][x] = labyrinth.path;
  return y = y + 2;
}
else if (d == RIGHT) {
  labyrinth.v[y][x + 1] = labyrinth.path;
  return x = x + 2;
}
else if (d == LEFT) {
  labyrinth.v[y][x - 1] = labyrinth.path;
  return x = x - 2;
}
else  {
}
}

1 个答案:

答案 0 :(得分:3)

您正在使您的无符号64位返回类型size_t下溢。

您正在检查xy是否低于零,但这还不够,因为0和1仍然太低,因为您减去2!

你得到的数字是十六进制的0xFFFFFFFFFFFFFFFF。这是无符号64位整数的最高可能值。

它来自计算1 - 2。是的,这应该是-1,但是因为您的移动功能不会返回已签名的号码而是未签名的号码(请查看相关文档) size_t),它不会是负面的! Instead, it wraps around to the highest possible number.

你可以想象这就像你得到的那样... 99999999999当你试图在纸上计算1 - 2时忽略了&#34;你不能从纸上的较小数字中减去更高的数字&#34; #34;规则。

作为旁注:我认为负面结果无论如何都是不受欢迎的,因为实际上你的巨大数字,一旦被添加到指针,将反过来“em>溢出回到正面,所以基本上它将起作用在你的情况下,同样是一个真正的-1,并且分段错误来自于在缓冲区开始之前访问某些东西,并不远远超出它,但它归结为同样的事情。 / p>

除此之外,没有必要return y = y - 2等。只需return y - 2