0

When executed, my code gives an exit status -1. I can show the input if it makes any difference. Can anybody find why this is happening?

INPUT:

6

N 10

E 2

S 3

W 4

S 5

E 8

I have already looked at the 2D integer array, and the variables in my code, looking for uninitialized ones, but I found no such errors. Can anybody see why I am getting exit status -1?

#include <iostream>
#include <algorithm>
#include <fstream>
using namespace std;

int main() {
  ofstream fout("mowing.out");
  ifstream fin("mowing.in");
  int n; fin >> n;
  int ans = 0;
  int field[2003][2003];
  for (int i = 0; i < 2003; i++) {
    for (int j = 0; j < 2003; j++) {
      field[i][j] = 0;
    }
  }
  int xloc = 1001, yloc = 1001, time = 0;
  for (int i = 0; i < n; i++) {
    char dir; int steps;
    fin >> dir >> steps;
    if (dir == 'N') {
      for (int j = 1; j < steps; j++) {
        yloc++;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
    if (dir == 'S') {
      for (int j = 1; j < steps; j++) {
        yloc--;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
    if (dir == 'W') {
      for (int j = 1; j < steps; j++) {
        xloc--;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
    else {
      for (int j = 1; j < steps; j++) {
        xloc++;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
  }
  if (ans == 0) fout << -1 << "\n";
  else fout << ans << "\n";
  return 0;
}
bruno
  • 32,421
  • 7
  • 25
  • 37
usercow
  • 67
  • 1
  • 11
  • Save yourself a couple `for` loops: `int field[2003][2003] = {0};` will initialize the first element of the array to 0, because that's what we asked for, and the rest to 0 because that's the default if you don't specify a value. – user4581301 Mar 27 '19 at 22:50
  • there are several problems in your code, see my answer – bruno Mar 27 '19 at 23:02

3 Answers3

2

in

fin >> dir >> steps;

you do not get the expected values

the first input is int n; fin >> n; and if the input file is like you indicate in the question the first value for dir will be the newline (after 6 in the input file) , then >> will definitively stay in error without doing something because after there is a N not compatible with steps being an int

To solve that problem

  • do not must mix int and char read without to be sure of the format and bypassing explicitly all necessary characters
  • or much more simple and secure do not read a char for dir but a string, so string dir; rather than char dir; and of course change the tests (dir == 'X') by (dir == "X") after where X is N, S or W

Probably you missed to add some else because you do :

if (dir == 'N') {
  ...
}
if (dir == 'S') {
  ...
}
if (dir == 'W') {
  ...
}
else {
  ...
}

so the last else normally for the case 'E' is also done for N and S case, probably you want

if (dir == 'N') { // in fact (dir == "N") see remark above
  ...
}
else if (dir == 'S') { // in fact (dir == "S") see remark above
  ...
}
else if (dir == 'W') { // in fact (dir == "W") see remark above
  ...
}
else {
  ...
}

I encourage you to check you open the files successfully, currently you suppose you did, and to check you read well in the input file

Note on my raspberrypi the stack is limited to 8192K (ulimit -s) so the size of field is too large, I changed it to be static to be able to execute the program (and I replaced the complicated initialization using the 2 for )

What is the expected content for mowing.out ? Doing the changes above I get 18


If I use the definition :

#include <iostream>
#include <algorithm>
#include <fstream>
using namespace std;

int main() {
  ofstream fout("mowing.out");

  if (!fout.is_open()) {
    cerr << "cannot open mowing.out" << endl;
    return -1;
  }

  ifstream fin("mowing.in");

  if (! fin.is_open()) {
    cerr << "cannot open mowing.int" << endl;
    return -1;
  }

  int n; 

  if ((!(fin >> n)) || (n < 0)) {
    cerr << "invalid number of couples" << endl;
    return -1;
  }

  int ans = 0;
  static int field[2003][2003] = { 0};
  int xloc = 1001, yloc = 1001, time = 0;

  for (int i = 0; i < n; i++) {
    string dir; int steps;

    if (!(fin >> dir >> steps)) {
      cerr << "error while reading fin & dir" << endl;
      return -1;
    }

    if (dir == "N") {
      for (int j = 1; j < steps; j++) {
        yloc++;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
    else if (dir == "S") {
      for (int j = 1; j < steps; j++) {
        yloc--;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
    else if (dir == "W") {
      for (int j = 1; j < steps; j++) {
        xloc--;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
    else {
      for (int j = 1; j < steps; j++) {
        xloc++;
        time++;
        if (field[xloc][yloc] != 0) ans = max(ans, time-field[xloc][yloc]);
        field[xloc][yloc] = time;
      }
    }
  }
  if (ans == 0) fout << -1 << "\n";
  else fout << ans << "\n";
  return 0;
}

Compilation and execution :

pi@raspberrypi:/tmp $ g++ -g -pedantic -Wextra -Wall e.cc
pi@raspberrypi:/tmp $ cat mowing.in 
6

N 10

E 2

S 3

W 4

S 5

E 8
pi@raspberrypi:/tmp $ ./a.out
pi@raspberrypi:/tmp $ cat mowing.out 
18
bruno
  • 32,421
  • 7
  • 25
  • 37
1

On top of excellent points made by bruno, I believe the root cause of the problem you encounter is a (nomen omen!) stack overflow.

Your array is too big to place on stack. Quick calculations (assuming sizeof(int) == 4):

2003 * 2003 * 4 B = 16048036 B = 15671.91015625 KiB = 15.304599761962890625 MiB

You're trying to allocate 15.3 MiB of memory on stack, whereas, according to this question, by default Windows allows 1 MiB and Linux usually allows 8 MiB.

You should either allocate memory on the heap by yourself or (better) use std::vector, like this:

std::vector<std::vector<int>> field (2003, std::vector(2003));
//it is already initialized above, no need for for loops ;)
//later on it can be used like regular array in most of the cases
Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
0

Can anybody see why I am getting exit status -1?

Not just anybody - you can do it!

enter image description here

... by using a debugger to stop your program at different points during its execution and check the values of n, ans and other variables.

I'm assuming you're using some IDE to edit and compile your code. IDEs typically have integrated debuggers. Examples:

It seems like students these days really aren't taught to debug... :-(

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • This was going on back in the 90's, too. in '93 I had a Computer Science professor tell the class that he wouldn't cover debugging because if you wrote your programs correctly you wouldn't have to debug. I thought he was just being funny until I talked to him later and found he wasn't. – user4581301 Mar 27 '19 at 23:38
  • @user4581301: Well, he was technically correct... It's also a waste of money to buy an eraser for your pencil work, because if you write down everything correctly you never have to erase anything :-) – einpoklum Mar 28 '19 at 00:12