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ループ本体では、 が有効なアドレスを持っていることは明らかですが、ループ本体を出てpieces[s]inでインデックス演算子を呼び出すとgetPiece、m_start は NULL になります。が有効なpieces[s]場合はループの最後の反復間で実行される演算はなく、ループ本体と同じインデックス演算子の呼び出し中の場合は NULL です。std::vector または std::vector のバグの私の誤用に関する洞察をいただければ幸いです。m_startgetPiecem_start

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 に答える