C ++向量下标超出范围,没有逻辑错误,无法弄清楚

时间:2017-03-03 23:04:00

标签: c++ vector

当我运行此代码时,它给出了一个调试断言失败,第1232行,向量下标超出范围。

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是stateTable的一个对象,定义如下:

typedef vector<vector<state> > stateTable;

代码中没有逻辑错误,但我得到了这个错误,我知道的一件事是我们的教师在Linux环境下编写和编译这段代码,而我在VC环境下这样做。这是什么原因?

2 个答案:

答案 0 :(得分:2)

方法reserve不会创建向量的新元素。它只是为未来的元素保留记忆。因此,您不能使用下标运算符来访问不存在的元素。

如果您想创建新元素,请使用方法reserve而不是方法resize

例如

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

或者只写

M.resize(n, std::vector<state>( size, WALL) );

答案 1 :(得分:2)

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

原因是向量的reserve()方法没有设置要使用的元素。以这种方式使用它们会在访问M[i]M[i][j]时提供未定义的行为。

更改M.reserve(size)M[i].reserve(size)的来电以使用resize()(即改为使用M.resize(size)M[i].resize(size)

不同之处在于resize()还确保元素可以使用(除其他外)。

差异反映了resize()设置可供使用的元素数量的目的,而reserve()则关注控制resize()的频率 - 以及调整其大小的其他操作容器 - 实际上重新分配内存。