记一个bug

花了2个多小时debug. 难受, 想哭.

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <utility>
#include <queue>
#include <cmath>
#include <algorithm>
#include <cstring>
#define MAX (5+1)
#define valid(x,y) (1<=x&&x<=N && 1<=y&&y<=M)

using namespace std;

int N, M, T;

bool a[MAX][MAX];
bool vis[MAX][MAX];

//typedef pair<int,int> xy;

struct xy {
    int x;
    int y;
    bool* vis;
    xy()= default;
    xy(int x_, int y_, bool* vis_):x(x_),y(y_){
      vis=vis_;
      }
};
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int bfs(int sx,int sy, int fx, int fy) {
  queue<xy> q;
//  vis[sx][sy]=true;  // 为什么多次一句要vis?因为不想初始化
  bool tmp_mem[MAX*MAX];
  memcpy(tmp_mem,vis, sizeof(tmp_mem));
  tmp_mem[sx*MAX+sy]=true;
  q.push(xy(sx,sy,tmp_mem));
  xy tmp;  // 用在后面
  int tmp_x, tmp_y;  // 用在后面
  int ans=0;
  while(!q.empty()) {
    tmp=q.front();
    q.pop();
    if(tmp.x==fx&&tmp.y==fy) {
      ++ans;
      continue;
    }
    for(int i = 0; i < 4; i++) {
      tmp_x=tmp.x+dx[i];
      tmp_y=tmp.y+dy[i];
      if(valid(tmp_x, tmp_y)&&!a[tmp_x][tmp_y]&&!tmp.vis[tmp_x*MAX+tmp_y]) {
        bool tmp_mem_in[MAX*MAX];
        memcpy(tmp_mem_in,tmp.vis,sizeof(tmp_mem_in));
        tmp_mem_in[tmp_x*MAX+tmp_y]=true;
        q.push(xy(tmp_x,tmp_y,tmp_mem_in));
        printf("qsize:%d\n",q.size());
      }
    }
  }
  return ans;
}

int main() {
  freopen("../IO/input.txt","r",stdin);
  int SX, SY, FX, FY;
  scanf("%d %d %d", &N, &M, &T);
  scanf("%d %d %d %d", &SX, &SY, &FX, &FY);
  int tmp_x, tmp_y;
  for (int i = 0; i < T; ++i) {
    scanf("%d %d", &tmp_x, &tmp_y);
    a[tmp_x][tmp_y]=true;
  }
  printf("%d", bfs(SX,SY,FX,FY));
}

这个对应的题目是, P1605.
给的输入是:

2 2 0
1 1 2 2

发现输出为1, 本来应该为2.
然后就单步调试.
发现诡异的事:
扩展节点(2,1), 放进去的时候, tmp_mem_in[13]=true. 但是当它被取出来的时候, tmp_mem_in[13]变成了false. 我感到震惊. 震惊了大概半个多小时, 怀疑这是queue实现的bug.
结果问题出在: 虽然是个数组, 但是bool tmp_mem_in[MAX*MAX];, 它是局部变量, 离开循环就被释放掉了!
启示: 不要在可见的局部空间试图开辟malloc, new以外的内存, 不会起作用的! 哪怕传给一个作用域更大的指针, 也毫无用处!

posted @ 2020-10-12 23:32  Tokubara  阅读(66)  评论(0)    收藏  举报