每当我调用std::vector<Domino>类型的dominoes.erase()时,我都会得到一个分段错误;即使我硬编码了这个值。
一个单独的成员函数调用dominoes.push_back()来加载数据,我可以使用pop_back()从向量中删除和返回一个domino,所以我知道里面有数据。我在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 );
}任何帮助都将不胜感激。谢谢!
发布于 2013-04-22 04:52:42
尝试通过删除所有不必要的代码(对象复制、向量访问...)来缩小错误范围。然后,如果问题确实来自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 );
}如果它仍然分段,那么问题来自于类Domino的析构函数。看看有没有什么可疑的东西。您可以通过注释析构函数的部分(或全部)来进行快速测试,以了解问题的来源。调用erase将调用Domino的析构函数。
如果析构函数没有实现,最好在其中实现一个带输出的析构函数(在cerr上,而不是在cout上),以了解它是到达那里还是更早崩溃。Domino是派生类吗?它里面有没有其他对象,或者只有一个基元类型的组合?
编辑
我快速浏览了您的代码:问题来自赋值运算符:
Domino & Domino::operator = ( const Domino & d )
{
*this = d;
}这是而不是它应该怎么写...我让您将其作为练习进行调试。
至于为什么这是bug的来源:你说erase崩溃了,但pop_back没有崩溃。两者之间的主要差异(实现差异,而不是明显的语义差异)在于,擦除会导致所有元素在删除元素后移位(使用=操作符),因为std::vector要求元素被连续存储。而pop只改变了尾部指针,而不改变容器的其余部分。
发布于 2013-04-22 04:54:03
从您向我们展示的内容可以看出,int index的值大于或等于dominoes.size()。否则,该代码将工作得很好。
我会检查random.NextNumber(dominoes.size())返回的内容。
此外,如果使用dominoes.size() == 0,则可能会出现此问题。在这种情况下,您将擦除dominoes.end()。
https://stackoverflow.com/questions/16135874
复制相似问题