调用vector.erase()时出现分段错误

Jer*_*gas 2 c++ std stdvector

每当我打电话给dominoes.erase()哪种类型的std::vector<Domino>我都会出现分段错误; 即使我硬编码这个值.

一个单独的成员函数调用dominoes.push_back()加载数据,我可以用来pop_back()从向量中删除并返回一个多米诺骨牌,所以我知道那里有数据.我有一个在Domino对象上创建的复制构造函数,并且工作得很好.我把它缩小到了dominoes.erase().

Domino::Domino( const Domino &d ) {
    left = d.getHighPip();
    right = d.getLowPip();

}
Domino DominoCollection::drawDomino( void )
{

    int index = random.nextNumber( dominoes.size()  );
    Domino d( dominoes[index] );
    dominoes.erase( dominoes.begin() + index );

    return Domino( d );
}
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激.谢谢!

Thi*_*aut 5

尝试通过删除所有不必要的代码(对象复制,矢量访问...)来缩小错误范围.然后,如果问题确实来自erase,请添加警卫以确保索引正确.请使用以下代码重试:

#include <cassert>
void DominoCollection::drawDomino( void )
{
    assert(dominoes.size() != 0 && "Your vector is empty");
    int index = random.nextNumber( dominoes.size()  );
    assert(index < dominoes.size() && "Buffer overflow...");
    dominoes.erase( dominoes.begin() + index );
}
Run Code Online (Sandbox Code Playgroud)

如果它仍然是段错误,则问题来自类的析构函数Domino.看看那里有什么可疑的东西.您可以通过注释析构函数(或所有部分)的部分来快速进行测试,以了解问题的来源.调用erase将调用析构函数Domino.

如果没有实现析构函数,那么在它中实现一个输出(on cerr,not cout)可能是一个好主意,以确定它是否到达或早先崩溃.是Domino一个派生类?它中是否有任何其他对象或仅包含原始类型的组合?

编辑

我快速浏览了你的代码:问题来自赋值运算符:

Domino & Domino::operator = ( const Domino & d )
{
    *this = d;
}
Run Code Online (Sandbox Code Playgroud)

不是它应该如何写...我让你调试它作为一个练习.

至于为什么那是bug的来源:你说erase崩溃但不是pop_back.两个(实施区别,而不是显而易见的语义差异)之间的主要区别是,擦除原因所有元素删除的那些(使用后移位=操作),因为std::vector需要将连续存储元件.pop只是更改尾指针而不会改变容器的其余部分.