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

#include <iostream>
#include <vector>
using namespace std;
#define HORIZONTAL 1
#define VERTICAL 2

int bit(int bits) {
  int ret = 0;
  while (bits != 0) {
    ret += bits & 0x00000001;
    bits >>= 1;
  }
  return ret;
}

int main() {
  int n, a, b, c, block, ret;
  while (cin >> n, n) {
    vector<int> data(5001, 0);
    data[5000] = 63; /* 63 = 0x11111 */
    ret = 0;

    while (n--) {
      cin >> a >> b >> c;
      c--;
      if (a == HORIZONTAL) {
        block = ((1 << b) - 1) << c;
        for (int i = 0; i < data.size() - 1; i++) {
          if (data[i + 1] & block) {
            data[i] += block;
            break;
          }
        }
      } else {
        block = 1 << c;
        for (int i = 0; i < data.size() - 1; i++) {
          if (data[i + 1] & block) {
            for (int j = 0; j < b; j++) {
              data[i - j] += block;
            }
            break;
          }
        }
      }

      vector<int>::iterator it = data.begin();
      while (it != data.end()) {
        if ((*it) == 31) {
          it = data.erase(it);
          it--;
        }
        it++;
      }
    }
    ret = 0;
    for (int i = 0; i < data.size() - 1; i++) {
      ret += bit(data[i]);
    }
    cout << ret << endl;
  }
}

Error: -6
free(): invalid next size (normal)


Fixed submission:

#include <iostream>
#include <vector>
using namespace std;

const int HORIZONTAL = 1;
const int VERTICAL = 2;
const int MAX_H = 5001;
const int WIDTH = 5;
const int N_BLOCK_MAX = 1000;

class Block {
public:
  int d, p, q;
  Block() {}
};

class Row {
public:
  int i[5];
  Row() {
    for (int m = 0; m < 5; m++)
      i[m] = 0;
  }
};

int n;
vector<Row> field;

bool isSetOk(Block b, int y) {
  if (b.d == HORIZONTAL) {
    for (int dx = 0; dx < b.p; dx++) {
      int xx = b.q + dx;
      if (field[y].i[xx])
        return false;
    }
    return true;
  } else if (b.d == VERTICAL) {
    for (int dy = 0; dy < b.p; dy++) {
      int yy = y + dy;
      if (field[yy].i[b.q])
        return false;
    }
    return true;
  }

  return false;
}

void setBlock(Block b, int y) {
  if (b.d == HORIZONTAL) {
    for (int dx = 0; dx < b.p; dx++) {
      int xx = b.q + dx;
      field[y].i[xx] = 1;
    }
  } else if (b.d == VERTICAL) {
    for (int dy = 0; dy < b.p; dy++) {
      int yy = y + dy;
      field[yy].i[b.q] = 1;
    }
  }
}

void checkErase() {
  vector<Row>::iterator iter = field.begin();
  while (iter != field.end()) {
    bool is_empty = true;
    bool is_fill = true;
    for (int x = 0; x < WIDTH; x++) {
      if ((*iter).i[x] != 0)
        is_empty = false;
      if ((*iter).i[x] == 0)
        is_fill = false;
    }

    if (is_fill) {
      field.erase(iter);
      continue;
    }

    if (is_empty)
      return;

    ++iter;
  }
}

int countBlock() {
  int retVal = 0;
  for (int y = 0; y < MAX_H; y++) {
    bool is_empty = true;
    for (int x = 0; x < WIDTH; x++) {
      if (field[y].i[x] != 0) {
        is_empty = false;
        retVal++;
      }
    }

    if (is_empty)
      break;
  }

  return retVal;
}

int main() {
  while (cin >> n, n) {
    field = vector<Row>(MAX_H);
    for (int i = 0; i < n; i++) {
      Block block;
      cin >> block.d;
      cin >> block.p;
      cin >> block.q;
      block.q--;

      for (int j = field.size() - 1; j >= 0; j--) {
        if (!isSetOk(block, j)) {
          setBlock(block, j + 1);
          break;
        }

        if (j == 0) {
          setBlock(block, 0);
        }
      }

      checkErase();

      /*
                              for(int y=9; y>=0; y--)
                              {
                                      for(int x=0; x<WIDTH; x++)
                                      {
                                              printf("%d ", field[y].i[x]);
                                      }
                                      printf("\\n");
                              }
                              printf("\\n");
      */
    }
    printf("%d\\n", countBlock());
  }
}