【发布时间】:2013-09-12 23:57:35
【问题描述】:
在逐步检查一些导致代码的奇怪分段错误时,我发现在将一个向量分配给另一个向量后,接收向量会任意损坏。以下是来自类的复制构造函数的代码 sn-p,该类具有数据成员 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 有一个有效地址,但是当它退出循环体并在getPiece 中调用pieces[s] 上的索引运算符时,m_start 为NULL。当m_start 有效时,在循环的最后一次迭代和getPiece 中,在与循环体中相同的索引运算符调用期间,m_start 为 NULL,没有对 pieces[s] 执行任何操作。对我滥用 std::vector 或 std::vector 中的错误的任何见解将不胜感激。
【问题讨论】:
-
std::vector<Piece> *pieces??为什么不std::vector<std::vector<Piece>> pieces? -
vector不属于性病,属于std。 -
你忘了
ClassName::getPiece吗? -
我对 std::vector 的误用或 std::vector 中的错误 ...很可能是前者;特别是使用动态分配的向量数组,而不是另一个向量来包含它们。呼应沃尔特的评论,使用
std::vector<std::vector<Piece>> pieces; -
这段代码看起来很奇怪......
Uint8属于std::size_t的位置,不必要的reserve()当复制将在下一行发生时