每当我拨打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 );
}
非常感谢任何帮助。谢谢!
答案 0 :(得分: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 );
}
如果它仍然是段错误,则问题来自类Domino
的析构函数。看看那里有什么可疑的东西。您可以通过注释析构函数的部分(或所有部分)来快速进行测试,以了解问题的来源。调用erase
将调用Domino
的析构函数。
如果没有实现析构函数,最好在其中实现一个输出(在cerr
上,而不是cout
),以确定它是否到达或早先崩溃。 Domino
是派生类吗?它中是否有任何其他对象或仅包含原始类型的组合?
修改
我快速浏览了你的代码:问题来自赋值运算符:
Domino & Domino::operator = ( const Domino & d )
{
*this = d;
}
这是 NOT 应如何编写...我让你调试它作为练习。
至于为什么这是bug的来源:你说erase
崩溃但不是pop_back
。两者之间的主要区别(实现差异,而不是明显的语义差异)是擦除导致所有元素在删除之后移位(使用=
运算符),因为std::vector
需要元素连续存储。而pop只是更改尾指针而不会改变容器的其余部分。
答案 1 :(得分:0)
根据您向我们展示的内容,int index
的值似乎大于或等于dominoes.size()
。否则,该代码可以正常工作。
我会检查random.NextNumber(dominoes.size())
返回的内容。
此外,dominoes.size() == 0
可能会出现此问题。在这种情况下,您将删除dominoes.end()
。