程序适用于ideone但不适用于本地(可能的内存错误)

时间:2013-03-27 13:51:16

标签: c++ algorithm memory

https://ideone.com/822Egw

我正在尝试解决BFS练习,当我使用ideone的编译器时,它可以工作并输出“2 4”,这是此输入的正确输出:

7 8
..#...##
.##.....
###.A..A
.#......
.#....A.
...A....
........

这是完整的代码:

#include <stdio.h>
#include <string.h>
#include <queue>

using namespace std;

#define MAX 1001

struct node
{
  int x;
  int y;
  int distance;
};

int l, c;
char grid[MAX][MAX], temp;
node clouds[MAX * MAX];
int n_clouds = 0;
int i, u;
int visited[MAX][MAX];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};
int n_min, n_max;

inline int max(int a, int b)
{
  return a > b ? a : b;
}

inline int min(int a, int b)
{
  return a < b ? a : b;
}

void read_input()
{
  scanf("%d %d", &l, &c);

  for (i = 0; i < l; i++)
  {
    for (u = 0; u < c; u++)
    {
      scanf(" %c", &temp);
      grid[i][u] = temp;

      if (temp == '#')
      {
        node cloud;
        cloud.x = u;
        cloud.y = i;

        clouds[n_clouds] = cloud;
        n_clouds++;
      }
    }
  }
}

void bfs(node start)
{
  queue<node> q;
  q.push(start);

  memset(visited, 0, sizeof visited);

  while (!q.empty())
  {
    node current = q.front();
    q.pop();

    int x = current.x;
    int y = current.y;
    int distance = current.distance;

    if (x < 0 || y < 0 || x >= c || y >= l || visited[y][x])
    {
      continue;
    }

    //printf("x: %d, y: %d\n", x, y);

    visited[y][x] = 1;

    if (grid[y][x] == 'A')
    {
      printf("distance: %d\n", distance);

      if (n_min == -1)
        n_min = distance;
      else
        n_min = min(n_min, distance);

      n_max = max(n_max, distance);
      return;
    }

    node node;
    node.distance = distance + 1;

    int k;
    for (k = 0; k < 4; k++)
    {
      node.x = x + dx[k];
      node.y = y + dy[k];
      q.push(node);

      //printf("node.x = %d, node.y = %d, k = %d\n", node.x, node.y, k);
    }
  }
}

int main()
{
  read_input();

  n_min = -1;
  n_max = -1;

  for (i = 0; i < n_clouds; i++)
  {
    bfs(clouds[i]);
  }

  printf("%d %d\n", n_min, n_max);

  return 0;
}

我正在使用g++ file.cpp -o file进行编译,这是我的4GB RAM笔记本电脑上的本地输出:

distance: 4196516
distance: 4196515
distance: 4196514
distance: 4196516
distance: 4196515
distance: 4196516
distance: 4196515
distance: 4196514
distance: 4196516
distance: 4196515
4196514 4196516

这与ideone的输出非常不同:

distance: 4
distance: 3
distance: 2
distance: 4
distance: 3
distance: 4
distance: 3
distance: 2
distance: 4
distance: 3
2 4

我猜这是某种可能由[MAX] [MAX]二维数组引起的内存错误,但我认为我可能有[1001] [1001]数组。我需要了解正在发生的事情。此外,我相信任何输入都会发生这种情况,因为有了这个,我也会得到奇怪的数字:

3 3
#..
...
..A

在ideone上我得到了正确的输出:

distance: 4
4 4

此程序应计算从任何云('#')到机场('A')的最小距离和最大距离。

这是valgrind输出,我认为它没有报告任何内存错误:

~/src/oni> valgrind ./nuvemcinzas < nuvemcinzas_input.txt 
==20861== Memcheck, a memory error detector
==20861== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==20861== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==20861== Command: ./nuvemcinzas
==20861== 
==20861== Conditional jump or move depends on uninitialised value(s)
==20861==    at 0x53954F1: vfprintf (vfprintf.c:1629)
==20861==    by 0x539E8D8: printf (printf.c:35)
==20861==    by 0x400C71: bfs(node) (in /home/david/src/oni/nuvemcinzas)
==20861==    by 0x400E25: main (in /home/david/src/oni/nuvemcinzas)
==20861== 
==20861== Use of uninitialised value of size 8
==20861==    at 0x53937EB: _itoa_word (_itoa.c:195)
==20861==    by 0x5395837: vfprintf (vfprintf.c:1629)
==20861==    by 0x539E8D8: printf (printf.c:35)
==20861==    by 0x400C71: bfs(node) (in /home/david/src/oni/nuvemcinzas)
==20861==    by 0x400E25: main (in /home/david/src/oni/nuvemcinzas)
==20861== 
==20861== Conditional jump or move depends on uninitialised value(s)
==20861==    at 0x53937F5: _itoa_word (_itoa.c:195)
==20861==    by 0x5395837: vfprintf (vfprintf.c:1629)
==20861==    by 0x539E8D8: printf (printf.c:35)
==20861==    by 0x400C71: bfs(node) (in /home/david/src/oni/nuvemcinzas)
==20861==    by 0x400E25: main (in /home/david/src/oni/nuvemcinzas)
==20861== 
distance: 4196516
==20861== Conditional jump or move depends on uninitialised value(s)
==20861==    at 0x400EB9: max(int, int) (in /home/david/src/oni/nuvemcinzas)
==20861==    by 0x400CBA: bfs(node) (in /home/david/src/oni/nuvemcinzas)
==20861==    by 0x400E25: main (in /home/david/src/oni/nuvemcinzas)
==20861== 
distance: 4196515
==20861== Conditional jump or move depends on uninitialised value(s)
==20861==    at 0x400C7B: bfs(node) (in /home/david/src/oni/nuvemcinzas)
==20861==    by 0x400E25: main (in /home/david/src/oni/nuvemcinzas)
==20861== 
==20861== Conditional jump or move depends on uninitialised value(s)
==20861==    at 0x400ED5: min(int, int) (in /home/david/src/oni/nuvemcinzas)
==20861==    by 0x400C9F: bfs(node) (in /home/david/src/oni/nuvemcinzas)
==20861==    by 0x400E25: main (in /home/david/src/oni/nuvemcinzas)
==20861== 
distance: 4196514
distance: 4196516
distance: 4196515
distance: 4196516
distance: 4196515
distance: 4196514
distance: 4196516
distance: 4196515
==20861== Conditional jump or move depends on uninitialised value(s)
==20861==    at 0x53954F1: vfprintf (vfprintf.c:1629)
==20861==    by 0x539E8D8: printf (printf.c:35)
==20861==    by 0x400E66: main (in /home/david/src/oni/nuvemcinzas)
==20861== 
==20861== Use of uninitialised value of size 8
==20861==    at 0x53937EB: _itoa_word (_itoa.c:195)
==20861==    by 0x5395837: vfprintf (vfprintf.c:1629)
==20861==    by 0x539E8D8: printf (printf.c:35)
==20861==    by 0x400E66: main (in /home/david/src/oni/nuvemcinzas)
==20861== 
==20861== Conditional jump or move depends on uninitialised value(s)
==20861==    at 0x53937F5: _itoa_word (_itoa.c:195)
==20861==    by 0x5395837: vfprintf (vfprintf.c:1629)
==20861==    by 0x539E8D8: printf (printf.c:35)
==20861==    by 0x400E66: main (in /home/david/src/oni/nuvemcinzas)
==20861== 
4196514 4196516
==20861== 
==20861== HEAP SUMMARY:
==20861==     in use at exit: 0 bytes in 0 blocks
==20861==   total heap usage: 49 allocs, 49 frees, 15,896 bytes allocated
==20861== 
==20861== All heap blocks were freed -- no leaks are possible
==20861== 
==20861== For counts of detected and suppressed errors, rerun with: -v
==20861== Use --track-origins=yes to see where uninitialised values come from
==20861== ERROR SUMMARY: 208 errors from 9 contexts (suppressed: 2 from 2)

1 个答案:

答案 0 :(得分:4)

您没有正确初始化云阵列中的距离值

尝试更改此

    node cloud;
    cloud.x = u;
    cloud.y = i;
    clouds[n_clouds] = cloud;

到这个

    node cloud;
    cloud.x = u;
    cloud.y = i;
    cloud.distance = 0;
    clouds[n_clouds] = cloud;