【问题标题】:Exit Status -1 on C++ ProgramC++ 程序的退出状态 -1
【发布时间】:2019-03-27 22:32:22
【问题描述】:

执行时,我的代码给出退出状态 -1。如果有任何不同,我可以显示输入。有人能找到为什么会这样吗?

输入:

6

N 10

E 2

S 3

W 4

S 5

E 8

我已经查看了二维整数数组和代码中的变量,寻找未初始化的变量,但没有发现此类错误。任何人都可以看到为什么我的退出状态为 -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;
}

【问题讨论】:

  • 为自己保存几个 for 循环:int field[2003][2003] = {0}; 会将数组的第一个元素初始化为 0,因为这是我们要求的,其余为 0,因为如果你不这样做,这是默认值'不指定一个值。
  • 你的代码有几个问题,看我的回答

标签: c++ c++11 exitstatus


【解决方案1】:

fin >> dir >> steps;

你没有得到预期值

第一个输入是int n; fin &gt;&gt; n;,如果输入文件与您在问题中指出的一样,dir 的第一个值将是换行符(输入文件中的 6 之后),然后是 @987654323 @ 将在不做任何事情的情况下明确地保持错误,因为在 Nsteps 不兼容之后是 int

解决这个问题

  • 在不确定格式和明确绕过所有必要字符的情况下,不得混合 intchar 读取
  • 或者更简单和安全的不为 dir 读取 char 而是一个字符串,所以string dir; 而不是char dir; 当然改变测试@ 987654326@ by (dir == "X") after where X is N, S or W

您可能错过了添加一些else,因为您这样做了:

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

所以最后一个 else 通常用于案例 'E' 也适用于 N 和 S 案例,可能你想要

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 {
  ...
}

我鼓励你检查你是否成功打开了文件,目前你认为你已经打开了,并检查你在输入文件中的阅读情况

请注意,在我的树莓派上,堆栈限制为 8192K (ulimit -s),因此 field 的大小太大,我将其更改为 static 以便能够执行程序(我用 2 for 替换了复杂的初始化)

mowing.out 的预期内容是什么?进行上述更改我得到 18


如果我使用定义:

#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;
}

编译和执行:

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

【讨论】:

    【解决方案2】:

    除了 bruno 提出的优秀观点之外,我相信您遇到问题的根本原因是(nomen omen!)堆栈溢出。

    您的数组太大无法放入堆栈。快速计算(假设sizeof(int) == 4):

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

    您正在尝试在堆栈上分配 15.3 MiB 的内存,而根据 this question,默认情况下 Windows 允许 1 MiB 而 Linux 通常允许 8 MiB。

    您应该自己在堆上分配内存,或者(最好)使用std::vector,如下所示:

    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
    

    【讨论】:

      【解决方案3】:

      任何人都可以看到为什么我的退出状态为 -1 吗?

      不只是任何人 - 可以做到!

      ...通过使用debugger 在程序执行期间的不同点停止程序并检查nans 和其他变量的值。

      我假设您正在使用一些 IDE 来编辑和编译您的代码。 IDE 通常具有集成的调试器。例子:

      好像students these days really aren't taught to debug... :-(

      【讨论】:

      • 这也发生在 90 年代。在 93 年,我有一位计算机科学教授告诉全班他不会涉及调试,因为如果您正确编写程序,您就不必调试。我以为他只是在开玩笑,直到后来我和他交谈发现他不是。
      • @user4581301: 嗯,他在技术上是正确的……为你的铅笔作品买一块橡皮擦也是浪费钱,因为如果你正确地写下所有东西,你就不必擦除任何东西:- )
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-02
      • 1970-01-01
      • 2013-08-11
      • 1970-01-01
      • 2020-07-03
      • 1970-01-01
      • 2010-12-22
      相关资源
      最近更新 更多