std :: vector的原因不明的行为

时间:2013-09-12 23:57:36

标签: c++ vector

在逐步执行导致代码的一些奇怪的分段错误时,我发现在将一个向量分配给另一个向量之后,接收向量任意破坏。以下是来自类的复制构造函数的代码片段,该类具有数据成员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具有有效地址,但是当它退出循环体并在pieces[s]中调用getPiece上的索引运算符时,m_start为NULL。在pieces[s]有效时,在循环的最后一次迭代之间m_start上没有执行任何操作,而在循环体中与索引运算符相同的调用期间,getPiece中没有执行任何操作{ {1}}为NULL。任何关于我在std :: vector中滥用std :: vector或bug的见解都将不胜感激。

1 个答案:

答案 0 :(得分: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>>

并复制了整件事。