我有一个类Piece
和类Board
,它们代表棋子和棋盘。在Board
类中,我有一个类型为Piece
的8*8指针数组,我希望它包含从索引0到63的指针。
变量'chess_board'周围的堆栈已损坏
Piece* m_Board[8 * 8];
Board() {
int i = 0;
//Black pawns
std::cout << i << std::endl;
m_Board[i] = new Rook(i++, 1);
m_Board[i] = new Knight(i++, 1);
m_Board[i] = new Bishop(i++, 1);
m_Board[i] = new Queen(i++, 1);
m_Board[i] = new King(i++, 1);
m_Board[i] = new Bishop(i++, 1);
m_Board[i] = new Knight(i++, 1);
m_Board[i] = new Rook(i++, 1);
//Black pieces
for (i; i < 16; i++) {
m_Board[i] = new Pawn(i, 1);
}
//Blank squares
std::cout << i << std::endl;
for (i; i < 48; i++) {
m_Board[i] = nullptr;
}
//White pawns
for (i; i < 56; i++) {
m_Board[i] = new Pawn(i, 0);
}
//White pieces
m_Board[i] = new Rook(i++, 0);
m_Board[i] = new Knight(i++, 0);
m_Board[i] = new Bishop(i++, 0);
m_Board[i] = new Queen(i++, 0);
m_Board[i] = new King(i++, 0);
m_Board[i] = new Bishop(i++, 0);
m_Board[i] = new Knight(i++, 0);
m_Board[i] = new Rook(i++, 0);
}
经过一些测试,我发现错误发生在最后m_Board[i] = new Rook(i++, 0);
行,其中变量i
从63变为64。如果我把那行改成m_Board[i] = new Rook(i, 0);
,错误就消失了。
我想知道i++
有什么影响,因为我认为m_Board[i] = new Rook(i++, 0);
类似于m_Board[i] = new Rook(i, 0); i++
?
我只访问数组的第63个元素,并将变量i
传递给Rook
对象的构造函数,之后变量i
将增加1。
这是如何产生错误的?
m_Board[i] = new Rook(i++, 0);
和m_Board[i] = new Rook(i, 0); i++;
不一样。这是两个不同的序列点。
引用cpp参考
A序列点是执行序列中所有先前求值产生的副作用的点。完整,后续评估也没有副作用。
也
在每个完整表达式的末尾有一个序列点(通常在分号处)。
a[i] = i++; // undefined behavior (until C++17)
请看以下文章:
- https://en.cppreference.com/w/cpp/language/eval_order(特别序列点规则部分)
- https://en.wikipedia.org/wiki/Sequence_point