1

在逐步检查一些导致代码的奇怪分段错误时,我发现在将一个向量分配给另一个向量后,接收向量会任意损坏。以下是来自一个类的复制构造函数的代码片段,该类具有一个数据成员,该数据成员vector<Piece> *pieces是一个包含类型向量的动态分配的数组Piece

ClassName::ClassName(const Class &other) // copy constructor of class
{
  ...
  for(SIDE_t s = 0; s < sides; s++)
  {
    pieces[s].reserve(other.pieces[s].size());
    pieces[s] = other.pieces[s];   //vector is completely valid here
    for(Uint8 p = 0; p < pieces[s].size(); p++)
    {
     //it continues validity throughout loop
      if(other.pieces[s][p].getCell() != NULL)
    pieces[s][p].setCell(cells + (other.pieces[s][p].getCell() - other.cells));

      if(pieces[s][p].getCell() == NULL)
        out.push_back(&pieces[s][p]);
    }
    if(other.flags[s] != NULL)
      flags[s] = getPiece(other.flags[s]->getValue(), other.flags[s]->getSide());
       // vector is invalid in scope of getPiece, which receives completely valid arguments
    else
      flags[s] = NULL;
  }
}

Piece * const ClassName::getPiece(const Uint8 num, const SIDE_t s) const 
{
    return (num>nPieces || s>sides || num == 0)? NULL:&pieces[s][num-1];
  // Right here during the member access function of pieces,
  // it is clear that the vector was corrupted some how
}

基本上在调试期间,我会进入pieces[s]成员访问功能。在循环体中,很明显m_start有一个有效的地址,但是当它退出循环体并在 in 上调用索引运算符时pieces[s]getPiecem_start 为 NULL。pieces[s]在循环的最后一次迭代之间没有执行任何操作whenm_start是有效的,并且在getPiece与循环体中的索引运算符相同的调用期间,m_start是 NULL。对我滥用 std::vector 或 std::vector 中的错误的任何见解将不胜感激。

4

1 回答 1

1

在我看来,您在这里有访问冲突:

return (num>nPieces || s>sides || num == 0)? NULL:&pieces[s][num-1];

首先(正如 Petr 所指出的),它应该是s>=sides.

其次,s这里的调用者不一样s。所以pieces[s]可能还没有被分配并且是一个空向量。要测试它使用

return (num>nPieces || s>=sides || num == 0)? NULL : &(pieces[s].at(num-1));

顺便说一句,如果您简单地使用,所有这一切都可以避免

std::vector<std::vector<Piece>>

并复制了整件事。

于 2013-09-13T00:10:33.913 回答