Reputation: 426
In Stepping through some weird segmentation fault causing code, I found that after the assignment of one vector to another, the receiving vector arbitrarily corrupts. The following is a code snippet from a copy constructor of a class which has a data member vector<Piece> *pieces
which is a dynamically allocated array containing vectors of type 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
}
Essentially during debugging, I would step into pieces[s]
member access function. In the loop body, it is evident that m_start
has a valid address, however when it exits the loop body and calls the index operator on pieces[s]
in getPiece
, m_start is NULL. There are no operations performed on pieces[s]
between the last iteration of the loop when m_start
is valid, and in getPiece
when during the same call of the index operator as in the loop body, m_start
is NULL. Any insight on my misuse of std::vector or bugs in std::vector would be appreciated.
Upvotes: 1
Views: 125
Reputation: 45414
It looks to me that you have an access violation here:
return (num>nPieces || s>sides || num == 0)? NULL:&pieces[s][num-1];
First (as pointed out by Petr), it should read s>=sides
.
Second, s
here is not the same as s
in the caller. So pieces[s]
may not have been assigned yet and is an empty vector. To test it use
return (num>nPieces || s>=sides || num == 0)? NULL : &(pieces[s].at(num-1));
Btw, all this would have been avoided had you simply used
std::vector<std::vector<Piece>>
and copied the whole thing.
Upvotes: 1