C++ 无法解释的std::vector行为

C++ 无法解释的std::vector行为,c++,vector,C++,Vector,在逐步分析一些奇怪的分段错误代码时,我发现在将一个向量分配给另一个向量之后,接收向量会任意损坏。下面是一个类的复制构造函数的代码片段,该类具有数据成员vector*pieces,该数据成员是一个动态分配的数组,包含Piece类型的向量 ClassName::ClassName(const Class &other) // copy constructor of class { ... for(SIDE_t s = 0; s < sides; s++) { pie

在逐步分析一些奇怪的分段错误代码时,我发现在将一个向量分配给另一个向量之后,接收向量会任意损坏。下面是一个类的复制构造函数的代码片段,该类具有数据成员
vector*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
}
ClassName::ClassName(const类和其他)//复制类的构造函数
{
...
用于(侧面s=0;sgetValue(),其他.flags[s]->getSide());
//向量在getPiece范围内无效,它接收完全有效的参数
其他的
标志[s]=NULL;
}
}
工件*const类名称::getPiece(const Uint8 num,const SIDE_t s)const
{
return(num>nPieces | | | s>sides | | num==0)?NULL:&pieces[s][num-1];
//就在这里,在碎片的成员访问功能期间,
//很明显,向量是如何损坏的
}

基本上在调试过程中,我会进入
parties[s]
成员访问功能。在循环体中,
m_start
显然有一个有效地址,但是当它退出循环体并调用
getPiece
pieces[s]
上的索引运算符时,m_start为空。当
m_start
有效时,循环的最后一次迭代与在
getPiece
中与循环体中相同的索引运算符调用期间,
m_start
为空时,在
pieces[s]
上没有执行任何操作。如果您对我滥用std::vector或std::vector中的bug有任何了解,我们将不胜感激。

我认为您在此处存在访问冲突:

return (num>nPieces || s>sides || num == 0)? NULL:&pieces[s][num-1];
首先(正如Petr所指出的那样),它应该是
s>=sides

其次,
s
这里与调用者中的
s
不同。因此,
parties[s]
可能尚未分配,并且是一个空向量。要测试它,请使用

return (num>nPieces || s>=sides || num == 0)? NULL : &(pieces[s].at(num-1));
顺便说一句,如果你只是简单地使用

std::vector<std::vector<Piece>>
std::vector
并复制了整个内容。

在我看来,您在此处存在访问冲突:

return (num>nPieces || s>sides || num == 0)? NULL:&pieces[s][num-1];
首先(正如Petr所指出的那样),它应该是
s>=sides

其次,
s
这里与调用者中的
s
不同。因此,
parties[s]
可能尚未分配,并且是一个空向量。要测试它,请使用

return (num>nPieces || s>=sides || num == 0)? NULL : &(pieces[s].at(num-1));
顺便说一句,如果你只是简单地使用

std::vector<std::vector<Piece>>
std::vector
并复制了整件事。

std::vector*parties
??为什么不
std::vector片段
vector
不属于std,它属于
std
。您是否忘记了
getPiece
上的
ClassName::
?我对std::vector的误用或std::vector中的bug。。。很可能是前者;特别是使用动态分配的向量数组,而不是使用另一个向量来包含它们。与沃尔特的评论相呼应,使用
std::vector片段这个代码看起来很奇怪
Uint8
std::size\u t
所属的位置,不必要的
reserve()
在下一行
std::vector*片段
发生复制时??为什么不
std::vector片段
vector
不属于std,它属于
std
。您是否忘记了
getPiece
上的
ClassName::
?我对std::vector的误用或std::vector中的bug。。。很可能是前者;特别是使用动态分配的向量数组,而不是使用另一个向量来包含它们。与沃尔特的评论相呼应,使用
std::vector片段这个代码看起来很奇怪
Uint8
std::size\t
所属的位置,不必要的
reserve()。此时我进入了操作员呼叫,num-1显然小于size。在函数执行之前,m_start已经为NULL。我想就是这样。是的,似乎在第一个循环之后再进行第二个循环确实会起作用。这并不完全是“避免”的,但是是的,这似乎更好。我不记得我以前为什么决定反对它了。此时我进入了操作员呼叫,num-1显然小于size。在函数执行之前,m_start已经为NULL。我想就是这样。是的,似乎在第一个循环之后再进行第二个循环确实会起作用。这并不完全是“避免”的,但是是的,这似乎更好。我不记得我以前为什么决定反对它了