Problem p00259 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;

int p;
string str;
char cstr[1 << 24];

int power(int x) {
  int n = p - 2;
  int res = 1;
  while (n) {
    if (n & 1)
      res = (res * x) % p;
    n >>= 1;
    x = (x * x) % p;
  }
  return res;
}

char *br(char *ss) {
  char *s = ss;
  int cnt = 0;
  while (true) {
    if (*s == '(')
      cnt++;
    else if (*s == ')')
      cnt--;
    if (cnt == 0)
      return s;
    s++;
  }
}

int calc(char *bg, char *ed) {
  /*
  for (char *s = bg; s != ed; s++){
          printf("%c", *s);
  }
  puts("");
  */

  char *s = bg;
  deque<int> arr;
  deque<char> op;

  int tn = 1;
  while (s != ed) {
    bool ln = false;

    if (*s >= '0' && *s <= '9') {
      arr.push_back(atoi(s));
      while (*s >= '0' && *s <= '9')
        s++;
      ln = true;
    } else if (*s == '+' || *s == '-') {
      if (tn == 1) {
        arr.push_back(atoi(s++));
        while (*s >= '0' && *s <= '9')
          s++;
        ln = true;
      } else {
        op.push_back(*s);
        s++;
      }
    } else if (*s == '*' || *s == '/') {
      op.push_back(*s);
      s++;
    } else if (*s == '(') {
      arr.push_back(calc(s + 1, br(s)));
      s = br(s) + 1;
      ln = true;
    }
    if (arr.size() && arr.back() == -1)
      return -1;
    if (ln && op.size() && (op.back() == '*' || op.back() == '/')) {
      char c = op.back();
      op.pop_back();
      int b = arr.back();
      arr.pop_back();
      int a = arr.back();
      arr.pop_back();
      if (c == '*')
        a = (a * b) % p;
      else if (c == '/') {
        if (b == 0)
          return -1;
        a = (a * power(b)) % p;
      }
      arr.push_back(a);
    }

    tn ^= 1;
  }
  while (op.size()) {
    char c = op.front();
    op.pop_front();
    int a = arr.front();
    arr.pop_front();
    int b = arr.front();
    arr.pop_front();
    if (c == '+')
      a = (a + b) % p;
    else if (c == '-') {
      a = (a - b + p) % p;
    }
    arr.push_front(a);
  }

  return arr.front();
}

int main() {
  while (true) {
    scanf("%d%*c", &p);
    if (p == 0)
      return 0;

    getline(cin, str);
    for (int i = 0; i < str.size(); i++) {
      if (str[i] == ' ')
        str.erase(i--, 1);
    }
    strcpy(cstr, str.c_str());
    int res = calc(cstr, cstr + strlen(cstr));
    if (res == -1)
      puts("NG");
    else {
      cout << str << " = " << res << " (mod " << p << ")" << endl;
    }
  }
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

int p;
string str;
char cstr[1 << 24];

int power(int x) {
  int n = p - 2;
  int res = 1;
  while (n) {
    if (n & 1)
      res = (res * x) % p;
    n >>= 1;
    x = (x * x) % p;
  }
  return res;
}

char *br(char *ss) {
  char *s = ss;
  int cnt = 0;
  while (true) {
    if (*s == '(')
      cnt++;
    else if (*s == ')')
      cnt--;
    if (cnt == 0)
      return s;
    s++;
  }
}

int calc(char *bg, char *ed) {
  /*
  for (char *s = bg; s != ed; s++){
          printf("%c", *s);
  }
  puts("");
  */

  char *s = bg;
  deque<int> arr;
  deque<char> op;
  while (s != ed) {
    int tn = 1;
    bool ln = false;

    if (*s >= '0' && *s <= '9') {
      arr.push_back(atoi(s));
      while (*s >= '0' && *s <= '9')
        s++;
      ln = true;
    } else if (*s == '+' || *s == '-') {
      op.push_back(*s);
      s++;
    } else if (*s == '*' || *s == '/') {
      op.push_back(*s);
      s++;
    } else if (*s == '(') {
      arr.push_back(calc(s + 1, br(s)));
      s = br(s) + 1;
      ln = true;
    }
    if (arr.size() && arr.back() == -1)
      return -1;
    if (ln && op.size() && (op.back() == '*' || op.back() == '/')) {
      char c = op.back();
      op.pop_back();
      int b = arr.back();
      arr.pop_back();
      int a = arr.back();
      arr.pop_back();

      if (c == '*')
        a = (a * b) % p;
      else if (c == '/') {
        if (b == 0)
          return -1;
        a = (a * power(b)) % p;
      }
      arr.push_back(a);
    }
  }
  while (op.size()) {
    char c = op.front();
    op.pop_front();
    int a = arr.front();
    arr.pop_front();
    int b = arr.front();
    arr.pop_front();
    if (c == '+')
      a = (a + b) % p;
    else if (c == '-') {
      a = (a - b + p) % p;
    }
    arr.push_front(a);
  }

  assert(arr.size() == 1);
  return arr.front();
}

int main() {
  while (true) {
    scanf("%d%*c", &p);
    if (p == 0)
      return 0;
    scanf("%*c");

    getline(cin, str);
    for (int i = 0; i < str.size(); i++) {
      if (str[i] == ' ')
        str.erase(i--, 1);
    }
    strcpy(cstr, str.c_str());
    int res = calc(cstr, cstr + strlen(cstr));
    if (res == -1)
      puts("NG");
    else {
      cout << str << " = " << res << " (mod " << p << ")" << endl;
    }
  }
}