-2

When I run this code it gives me a debug assertion failed, line 1232, vector subscript out of range.

Maze::Maze(bool verbose = false)
// verbose == true means an intro and prompts for input will be printed
{
  int i, j, dimension;

  if (verbose) {
    cout << "Welcome to the Rat in the Maze program, where we will find a\n"
     << "path from the start cell to the end cell of a maze so that Remy\n"
     << "may escape.  You will first enter the data specifying the maze.\n"
     << "After that, if escape is possible, we will show an escape path\n"

         << "Enter the number of rows and columns of the maze: " << endl;
  }   
  cin >> dimension;
  size = dimension+2; // add the hedge rows and columns
  if (verbose)
    cout << "Enter the row and column indices of the start: " << endl;
  cin >> start;
  if (verbose)
    cout << "Enter the row and column indices of the exit: " << endl;
  cin >> exitpos;


/Here is where I got the error:/
  M.reserve(size);
  for (i = 0; i < size; i++) {
    M[i].reserve(size);
    for (j = 0; j < size; ++j)
      M[i][j] = WALL;
  }

  if(verbose) {
    cout << "For each row, enter the column indices of the open squares\n";
    cout << "Terminate the row input with a non-positive value" << endl;
  }
  for (i = 1; i <= size-2; i++) {
    if (verbose)
      cout << "Row " << i << ": ";  
    cin >> j;
    assert(j < 1 || 1 <= j && j <= size-2);

    while (j > 0){
      M[i][j] = OPEN;
      cin >> j;
      assert(j < 1 || 1 <= j && j <= size-2);
    };
  }

  if (!(M[start.row][start.col] == OPEN)) 
    M[start.row][start.col] = OPEN;
}

M is an object of stateTable, which defined as below:

typedef vector<vector<state> > stateTable;

There is no logic error in the code but I got this error, and one thing I know is our instructor wrote and compile this code under Linux environment while I'm doing that under VC environment. Is that the reason?

Boooooo
  • 157
  • 3
  • 12

2 Answers2

4

The method reserve does not creates new elements of a vector. It just reserve memory for future elements. So you may not use the subscript operator to access non-existent elements.

Instead of the method reserve use method resize if you want to create new elements.

For example

  M.resize(size);
  for (i = 0; i < size; i++) {
    M[i].resize(size);
    for (j = 0; j < size; ++j)
      M[i][j] = WALL;
  }

Or just write

M.resize(n, std::vector<state>( size, WALL) );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
3
 M.reserve(size);
 for (i = 0; i < size; i++)
 {
     M[i].reserve(size);
     for (j = 0; j < size; ++j)
         M[i][j] = WALL;
 }

The reason is that a vector's reserve() method does not set up the elements for use. Using them in this way gives undefined behaviour on accessing M[i] and M[i][j].

Change the calls of M.reserve(size) and M[i].reserve(size) to use resize() (i.e. to use M.resize(size) and M[i].resize(size) instead.

The difference is that resize() also ensures the elements are ready for use (among other things).

The difference reflects the purpose of resize() as being to set the number of elements available for use, whereas reserve() is concerned with controlling how often resize() - and other operations that resize the container - actually reallocate memory.

Peter
  • 35,646
  • 4
  • 32
  • 74
  • The accepted answer [here](http://stackoverflow.com/a/7397862/1640610) elaborates on Peter's explanation of the difference between `resize()` and `reserve()`. – GigaRohan Mar 03 '17 at 23:31
  • Thank you, I guess I need more understanding. – Boooooo Mar 03 '17 at 23:31