[英]Unexplained Behavior with std::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。 当m_start
有效时,在循环的最后一次迭代之间,以及在与循环体相同的索引运算符调用期间,在getPiece
中,没有对pieces[s]
执行任何操作,而m_start
为NULL。 对于我滥用std :: vector或std :: vector中的错误的任何见解,将不胜感激。
在我看来,您在这里遇到访问冲突:
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>>
并复制了整个内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.