每当我调用dominoes.erase()
类型的std::vector<Domino>
时,都会遇到分段错误;即使我将值硬编码。
一个单独的成员函数调用dominoes.push_back()
加载数据,并且我能够使用pop_back()
从 vector 中删除并返回一个多米诺骨牌,所以我知道里面有数据。我已经在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 );
}
任何帮助将不胜感激。谢谢!
最佳答案
尝试通过删除所有不必要的代码(对象复制, vector 访问...)来缩小错误的范围。然后,如果问题确实来自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;
}
这是而不是应该如何编写...我让您调试一下作为练习。
至于为什么这是错误的根源:您说
erase
崩溃了,但不是pop_back
。两者之间的主要区别(实现上的区别,不是明显的语义上的区别)是,擦除会导致所有元素在删除后都发生移位(使用=
运算符),因为std::vector
要求元素要连续存储。而pop只会更改尾指针,而不会更改容器的其余部分。关于c++ - 调用vector.erase()时出现段错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16135874/