从 100 递减到 0 时向量下标超出范围

Vector Subscript out of range when decrementing from 100 to 0

我调试了这个错误,我无法理解这个向量下标超出范围的原因。我也看过这个 link 但没有用:
Vector subscript out of range

我有一个名为 board 的 class,它有一个私有数据成员 vector<int> m_Board_board。在 board 构造函数中,我将此变量从 1 初始化为 100 并使用 friend operator << 函数从最后打印到最后,如下所示:

#ifndef BOARD_H
#define BOARD_H

#include <iostream>
#include <vector>

using std::vector;
using std::ostream;

class Board
{
private:
   vector<int> m_Board_board;
public:
   Board()
   {
      for (int i = 1; i < 101; ++i)  {
         m_Board_board.push_back(i);
      }
   }

   friend ostream& operator << (ostream& os, Board board)
   {
      for (int i = 100; i > 0; --i) {
         os << board.m_Board_board[i] << '\n';
      }
      return os;
   }
};

#endif // !BOARD_H

在我的 main 函数中,我正在打印电路板。

#include "Board.h"    
using std::cout;

int main()
{
   Board board;
   cout << board;
   system("pause");
}

这会产生以下错误:https://i.stack.imgur.com/TWVQF.png

现在奇怪的是,如果我将 operator << 函数更改为从头到尾打印,它会按预期工作!

#ifndef BOARD_H
#define BOARD_H

#include <iostream>
#include <vector>
using std::vector;
using std::ostream;

class Board
{
private:
   vector<int> m_Board_board;

public:
   Board() 
   {
      for (int i = 1; i < 101; ++i) {
         m_Board_board.push_back(i);
      }
   }

   friend ostream& operator << (ostream& os, Board board)
   {
      for (int i = 0; i < 100; ++i) {
         os << board.m_Board_board[i] << '\n';
      }
      return os;
   }
};
#endif // !BOARD_H

他们都在做同样的事情,但是一个抛出 vector subscription out of range 错误,而另一个工作正常。现在,在我收到说我必须使用迭代器的评论之前,我用迭代器尝试了它们,同样的事情发生了,这让我尝试使用普通的整数循环来确定问题是否出在使用迭代器上。然而,它不是迭代器,而是奇怪的东西!

然而,在第一种情况下,当我从 99 迭代到 0 时,它工作得很好,但它不打印第一个元素(很明显!)。

那么,当我开始从 100 下降到 0 时,为什么它会超出范围?

他们做的不一样!

你的 m_Board_board 中有 100 个元素,这意味着索引从 0, 1, 2,..., 99 开始,在第一个代码中,在循环中

for (int i = 100; i > 0; --i) {

您正在启动索引 100。这是试图访问向量 vis std::vector::operator[] 中的 non-existing 元素,即 access out of bounds undefined behaviour。那是任何事情都可能发生的。在你的情况下,你遇到了程序崩溃。

您应该从 99 开始而不是具有定义的行为

friend ostream& operator << (ostream& os, Board const& board) /* noexcept */
//                                              ^^^^^^^--> also pass the object by const-ref
{
   for (int i = 99; i >= 0; --i) {
      os << board.m_Board_board[i] << '\n';
   }
   return os;
}

或者借助反向迭代器

#include <algorithm> //  std::copy
#include <iterator>  

friend ostream& operator << (ostream& os, Board const& board) /* noexcept */
//                                              ^^^^^^^--> also pass the object by const-ref
{
   std::copy(board.m_Board_board.crbegin(), board.m_Board_board.crend(),
      std::ostream_iterator<int>(os, "\n"));
   return os;
}

这里是a working demo.