为啥这个向量代码会出现分段错误?
Posted
技术标签:
【中文标题】为啥这个向量代码会出现分段错误?【英文标题】:Why is there a Segmentation Fault from this vector code?为什么这个向量代码会出现分段错误? 【发布时间】:2014-04-08 18:51:01 【问题描述】:当我在 Code::Blocks 中执行此代码时,我遇到了分段错误。为什么?我已经使用调试并没有找到原因。任何帮助都是有用的。
调试器显示它来自向量 push_back 方法,但特别是在复制构造函数中使用的“this”指针上。
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cmath>
const int MAX_COL = 7, MAX_ROW = 6;
const int NOPLAYER = 0, PLAYER1 = 1, PLAYER2 = 2;
const int NOTHING = 123;
int movesBeingStored = 0;
int movesCreated = 0;
class Move
public:
Move() : row(-1), col(-1), plr(-1)
//std::cout << "Placed @" << col << "," << row << std::endl;
++movesBeingStored;
++movesCreated;
std::cout << "+Now " << movesBeingStored << " move(s), Created " << movesCreated << std::endl;
;
Move(int r, int c, int p) : row(r), col(c), plr(p)
++movesBeingStored;
++movesCreated;
std::cout << "+Now " << movesBeingStored << " move(s), Created " << movesCreated << std::endl;
;
~Move()
--movesBeingStored;
std::cout << "-Now " << movesBeingStored << " move(s)" << std::endl;
;
int getRow() const return row;
int getCol() const return col;
int getPlayer() const return plr;
Move(const Move* other)
++movesBeingStored;
++movesCreated;
std::cout << "+Now " << movesBeingStored << " move(s), Created " << movesCreated << std::endl;
col = other->getCol();
row = other->getRow();
plr = other->getPlayer();
Move(const Move& other)
++movesBeingStored;
++movesCreated;
std::cout << "+Now " << movesBeingStored << " move(s), Created " << movesCreated << std::endl;
col = other.getCol(); //This line causes a segment fault
row = other.getRow();
plr = other.getPlayer();
bool operator== (const Move& other) const
return (&other == this);
private:
int row, col, plr;
;
int board[MAX_COL * MAX_ROW];
std::vector<Move> moves;
bool isFull[MAX_COL];
int tops[MAX_COL];
int currentPlayer = PLAYER1;
int checkedCollumns = 0;
void randomize( void ) srand(time(NULL));
void startBoard( void );
void placeMove(int col, int player);
void popMove();
int checkwin(int curPlayer);
int checkMove(int depth, int& bestCol, int curP, int checkP);
int randomInt(int min, int max);
void printMoves( void );
int main()
startBoard();
randomize();
int col = -1;
int pts = checkMove(2, col, PLAYER1, PLAYER1);
if(col == -1)
std::cout << "No best move" << std::endl;
else
std::cout << "Best move: Col " << col << std::endl;
if(pts == NOTHING)
std::cout << "Nothing happens" << std::endl;
else
std::cout << "Gives " << pts << " points" << std::endl;
void startBoard( void )
for(int i = 0; i < MAX_COL; ++i)
isFull[i] = false;
tops[i] = 0;
for(int p = 0; p < MAX_COL * MAX_ROW; ++p)
board[p] = NOPLAYER;
void placeMove(int col, int player)
if(col < 0 || col >= MAX_COL)
return;
if(isFull[col])
return;
if(player != PLAYER1 && player != PLAYER2)
player = PLAYER1;
moves.push_back(Move(col, tops[col], player));
board[col + tops[col] * MAX_COL] = player;
++tops[col];
isFull[col] = (tops[col] == MAX_ROW);
void popMove()
if(moves.empty())
return;
Move move = moves.back();
moves.pop_back();
int col = move.getCol(), row = move.getRow();
board[col + row * MAX_COL] = NOPLAYER;
tops[col] = row;
isFull[col] = (tops[col] == MAX_ROW);
int checkwin(int curPlayer)
if(randomInt(0,5) != 1)
return NOTHING;
return randomInt(0,4);
int checkMove(int depth, int& bestCol, int curP, int checkP)
int pts = NOTHING, col = -1, p = NOTHING, c = -1;
if(depth <= 0)
if(moves.empty())
bestCol = -1;
return NOTHING;
Move move = moves.back();
bestCol = move.getCol();
pts = checkwin((move.getPlayer());
if(move.getPlayer() != checkP && pts != NOTHING)
pts = -pts;
return pts;
for(int i = 0; i < MAX_COL; ++i)
std::cout << "C: " << checkedCollumns;
std::cout << "\tD: " << depth;
std::cout << "\tM: " << moves.size();
std::cout << std::endl;
if(isFull[i])
continue;
++checkedCollumns;
placeMove(i, curP);
p = checkMove(depth - 1, c, ((curP == PLAYER1)?PLAYER2:PLAYER1), checkP);
popMove();
if(p != NOTHING && checkP != curP)
p = -p;
if(col == -1)
col = i;
pts = p;
continue;
if(pts == NOTHING && p != NOTHING && p >= 0)
col = i;
pts = p;
continue;
if(pts != NOTHING && p != NOTHING && p > pts)
col = i;
pts = p;
bestCol = col;
return pts;
int randomInt(int min, int max)
double per = (double)(rand() % RAND_MAX) / RAND_MAX;
return min + (max - min) * per;
void printMoves( void )
std::cout << "M:";
if(moves.empty())
std::cout << " --\t" << moves.size();
return;
Move m;
for(unsigned int i = 0; i < moves.size(); ++i)
m = moves.at(i);
std::cout << " " << m.getCol() << "," << m.getRow() << "";
std::cout << "\t" << moves.size();
【问题讨论】:
您是否查看过调用堆栈以了解您的哪些函数触发了对 push_back 的调用? 为什么Move::operator==
比较指针值?这是没有意义的,因为你有一个 operator= 让 operator== 违反直觉。
@TricksterTales - 我的意思是:Move m1; Move m2; m2 = m1; if (m2 == m1) ... // What, not equal?? I just made them equal!
看到问题了吗?我使 m1 等于 m2,但是您的代码现在告诉我它们不相等。那段代码会让我发疯。
@TricksterTales 你应该问为什么它只在第 64 次迭代时才崩溃,当 moveCreated == 65 时。这也是第一次使用 Move(const Move& other)。
@TricksterTales 在旁注中,如果您注释掉这些分配并输入全零,它似乎也一直运行到最后。 col = 0;//other.getCol(); row = 0;//other.getRow(); plr = 0;//other.getPlayer();
【参考方案1】:
一个非常微不足道的错误,以一种非常晦涩的方式表现出来。段错误是由向量试图在无效位置构造对象引起的。为什么?因为void popMove()
中的以下行:
board[col + row * MAX_COL] = NOPLAYER;
这一行有一个由无效坐标(0, 6)引起的缓冲区溢出,它覆盖了moves
中的内部内存指针。这就是问题所在,解决方案取决于您。
【讨论】:
我应该提一下无效坐标似乎是由void placeMove(int col, int player)
中的moves.push_back(Move(col, tops[col], player));
引起的。你可能打算写moves.push_back(Move(tops[col], col, player));
。据我所知,我想这几乎就是您需要做的所有解决问题的工作。
是的,谢谢您的留言。我会再试一次并编辑顶部代码,看看这是否是问题
是的,这正是问题所在,它奏效了。谢谢,那是我的一个愚蠢的错误。此外,缺少括号,但是是的,改变了论点。再次感谢。以上是关于为啥这个向量代码会出现分段错误?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 C++ 标准向量在分配或调整大小时会出现段错误? [关闭]