C++ 对象指针的优先级队列在运行时错误为无效堆

Posted

技术标签:

【中文标题】C++ 对象指针的优先级队列在运行时错误为无效堆【英文标题】:C++ Priority queue of object pointers at runtime error as invalid heap 【发布时间】:2014-03-25 17:12:47 【问题描述】:

我已经尝试在 C++ 中实现一个优先级队列大约 5 个小时了。

我不相信我的比较函子正在做它应该做的事情,但对于我的生活,我无法弄清楚为什么。

在我的 Node 类的底部我有一个结构 CompareNode,Node 类有一个函数来返回一个 int 成员变量。

 class Node
 
 public:
     Node();
     ~Node();
     Node(const Node &obj);

     int GetX() const  return x; 
     int GetY() const  return y; 
     int GetG() const  return g; 
     int GetH() const  return h; 
     int GetF() const  return f; 
     int GetTerrainPenalty() const  return terrainPenalty; 
     bool GetOpenList() const  return openList; 
     bool GetClosedList() const  return closedList; 
     Node* GetParentNode() const  return parentNode; 
     std::vector<Node*> const GetNeighbours()  return neighbours; 

     void SetX(int x)  this->x = x; 
     void SetY(int y)  this->y = y; 
     void SetG(int g)  this->g = g; 
     void SetH(int h)  this->h = h; 
     void SetF(int f)  this->f = f; 
     void SetTerrainPenalty(int t)  this->terrainPenalty = t; 
     void SetOpenList(bool b)  this->openList = b; 
     void SetClosedList(bool b)  this->closedList = b; 
     void SetParentNode(Node* n)  this->parentNode = n; 
     void SetNeighbours(std::vector<Node*> n)  this->neighbours = n; 

     void AddNeighbour(Node* n)  neighbours.push_back(n); 

     // Manahattan Distance
     void CalculateH(Node* end);
     void CalculateF();

 private:
     int x;
     int y;
     int g;
     int h;
     int f;
     int terrainPenalty;
     bool openList;
     bool closedList;
     Node* parentNode;
     std::vector<Node*> neighbours;

 ;

 struct CompareNode
 
     bool operator()(const Node* lhs, const Node* rhs) const
     
         return lhs->GetF() < rhs->GetF();
     
 ;

在我的 main.cpp 中,我声明了优先级队列。

 std::priority_queue<Node*, std::vector<Node*>, CompareNode> openList;

我收到 Debug Assertion Failed 错误,Invalid Heap。

在调试时,似乎当我调用 openList.top() 时它没有返回正确的节点。

任何想法我做错了什么?

【问题讨论】:

能否请您发布您的节点的结构.. 如果 CompareNode 得到两个 const Node* 不应该是 priority_queue, CompareNode> 吗? 没有 priority_queue, CompareNode> 我无法将指针对象推送到队列中。例如节点* n; openList.push(n); 为什么你需要 c++ 来完成你的任务?看起来你没有时间真正学习它。如果你不真的学习 c++,你就有麻烦了。改用 python(或 java 或 c#)。 @lowtech 很有帮助.. 【参考方案1】:

我的心理调试能力告诉我,由于您没有为您的 Node 实现复制构造函数,因此您不小心将其复制到某个地方,从而导致双重删除。

【讨论】:

会放入一个拷贝构造函数,如果能解决这个问题会告诉你。 我同意如果没有复制构造函数并且有两个涉及指针的内部数据成员,默认的复制构造函数每次都会导致问题。 我实现了复制构造函数,但我仍然得到相同的调试断言无效堆错误。 @kev3kev3 听起来复制构造函数主体没有执行深层复制。 @kev3kev3 在使用标准库容器(例如向量、地图、列表、队列等)时,最好始终为存储的对象实现 ==&lt; 运算符一个容器内。在容器内存储指针变得更加复杂,以便在容器被销毁之前正确释放内存。当元素是指针时,容器析构函数不会调用每个元素的析构函数。正如 lowtech 上面所说,为了继续提供帮助,需要所有实施细节。

以上是关于C++ 对象指针的优先级队列在运行时错误为无效堆的主要内容,如果未能解决你的问题,请参考以下文章

c++ 将指针推入指针优先级队列会导致立即 valgrind 错误

如何在 C++ 中跟踪无效指针?

将元素推入优先级队列时,二进制表达式的操作数无效

如何解决 munmap_chunk():C++ 中的无效指针错误

C++ 我在设置我创建的类的优先级队列时遇到问题

优先级队列实现为单链接未能在插入时更新指针引用