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我的心理调试能力告诉我,由于您没有为您的 Node
实现复制构造函数,因此您不小心将其复制到某个地方,从而导致双重删除。
【讨论】:
会放入一个拷贝构造函数,如果能解决这个问题会告诉你。 我同意如果没有复制构造函数并且有两个涉及指针的内部数据成员,默认的复制构造函数每次都会导致问题。 我实现了复制构造函数,但我仍然得到相同的调试断言无效堆错误。 @kev3kev3 听起来复制构造函数主体没有执行深层复制。 @kev3kev3 在使用标准库容器(例如向量、地图、列表、队列等)时,最好始终为存储的对象实现==
和 <
运算符一个容器内。在容器内存储指针变得更加复杂,以便在容器被销毁之前正确释放内存。当元素是指针时,容器析构函数不会调用每个元素的析构函数。正如 lowtech 上面所说,为了继续提供帮助,需要所有实施细节。以上是关于C++ 对象指针的优先级队列在运行时错误为无效堆的主要内容,如果未能解决你的问题,请参考以下文章
c++ 将指针推入指针优先级队列会导致立即 valgrind 错误