使用STL priority_queue
我尝试使用pop()
时会收到错误“无效堆”。我可以将我的值推送到队列中,队列的top()
是我期望和可访问的。 pop()
,当它重新堆叠时,似乎有问题。
我存储指向队列中模板化类的指针。我有比较重载:
template <class type>
class vertexPriorityCompare
{
public:
bool operator()(Vertex<type>* leftVertex, Vertex<type>* rightVertex) const
{
if(leftVertex->getDistanceFromSource() < 0 && rightVertex->getDistanceFromSource() < 0)
{
return false;
}
else if(leftVertex->getDistanceFromSource() < 0)
{
return true;
}
else if(rightVertex->getDistanceFromSource() < 0)
{
return false;
}
else
{
return leftVertex->getDistanceFromSource() > rightVertex->getDistanceFromSource();
}
}
};
priority_queue
是班级的私人成员:
priority_queue< Vertex<type>*, vector< Vertex<type>* >, vertexPriorityCompare<type> > Q;
过载以它的方式起作用,因为负距离被认为是无穷大,总是比其他任何东西都大;为了表示无穷大,距离初始化为-1。队列需要保持最小,但在顶部是非负的。
我取消引用重载中的指针,这是我在那里允许的吗?而且,还有另一个我需要重载的运算符吗?
我会附上代码,但如果我这样做,它会吓跑人们。要求查看更多内容,我会附加到另一条消息。
我动态地声明一个指向指针的数组,这些是被推送的,因为我假设priority_queue
通过引用存储,所以如果我只是将一个在循环中声明的指针放入队列中,那么指针就会消失范围。这些指针指向正确的Vertex<type>
,并存在于整个函数中。
Visual Studio 2008调试器将我带入'stdthrow.cpp'第24行。
答案 0 :(得分:3)
这可能是你的比较功能。要进行测试,请将其替换为仅比较指针的简单版本:
bool operator()(...)
{
return leftVertex<rightVertex;
}
如果问题不再出现,则问题是您的比较功能无效。您的比较器必须定义"strict-weak ordering"。我不足以表明它没有,但我打赌就是这样。
答案 1 :(得分:3)
比较函数看起来很好,如果对象getDistanceFromSource()
的值没有改变,而该对象在队列中。这确保了吗?或者是否有可能影响getDistanceFromSource()
的对象,当它们在队列中或队列最初被填充时?
答案 2 :(得分:0)
你从哪里调用这个函数?
我的猜测是无效堆是一个指针,你从“this function caller”代码传入函数。或者当你从矢量中取出顶点时,你可能会走出界限。
我认为该功能没有任何问题。
请提供堆栈跟踪
答案 3 :(得分:0)
如果没有callstack,确定问题是什么有点困难,但是你要么没有正确分配Vertex<...>
,要么从堆栈中释放Vertex<...>
,要么没有初始化Vertex<...>*
有效值。
答案 4 :(得分:0)
这一点让我害怕:
我动态声明一个数组 指针指针,这些是什么 被推,因为我认为 priority_queue按引用存储,所以 如果我只是把一个指针声明 循环进入队列,即指针 超出范围。这些指针 指向正确的顶点,并存在 整个功能。
目前还不清楚你是如何填充队列的。 您必须创建Vertex对象,它们必须保留在内存中,并在队列中的整个时间内返回相同的距离。
队列不通过引用存储,它存储副本 - 但在这种情况下,您输入的是指针,因此它复制指针,指针仍将指向您分配的原始对象。
我认为我们需要一个简短的完整示例才能获得更多。