我正在尝试从Java改编为C ++,当我从STL priority_queue中弹出一个项目时,我不确定管理内存的正确方法。
我是否应该使用delete来清除从队列中删除的不再需要的项目?如果是这样,怎么样?如果没有,为什么不呢?
我自己写了一个小程序来学习如何使用priority_queue(下面的代码)。在这个程序中,如果存在内存泄漏,这没什么大不了的,因为它的规模如此之小,并且结束得如此之快。但我想学习正确的做事方式,这样我就可以编写一个程序来正确处理更大的队列而不会造成内存泄漏。
我不明白的是:top()返回一个引用而不是一个指针。但是我不能在引用上使用delete,可以吗?
有人能指出我在正确的方向吗?
--------------------
struct PathCost{
int dest;
int cost;
PathCost(int _dest, int _cost){
dest = _dest;
cost = _cost;
}
bool operator<(PathCost other) const;
bool operator>(PathCost other) const;
};
bool PathCost::operator<(PathCost other) const{
return cost < other.cost;
}
bool PathCost::operator>(PathCost other) const{
return cost > other.cost;
}
int main(){
PathCost pc = PathCost(1, 2);
pc = PathCost(3, 4);
PathCost* pcp = new PathCost(5, 6);
delete pcp;
priority_queue<PathCost,
vector<PathCost>,
greater<vector<PathCost>::value_type> > tentativeQ;
cout << "loading priority queue ...\n";
tentativeQ.push(PathCost(8, 88));
tentativeQ.push(PathCost(5, 55));
tentativeQ.push(PathCost(7, 77));
tentativeQ.push(PathCost(4, 44));
cout << "\nlist items on queue in priority order ...\n";
while (!tentativeQ.empty()){
pc = tentativeQ.top();
cout << "dest:" << pc.dest << " cost:" << pc.cost << endl;
tentativeQ.pop();
/* DO I NEED TO DO MEMORY CLEANUP AT THIS POINT? */
}
}
答案 0 :(得分:2)
我是否应该使用delete来清除从队列中删除的不再需要的项目?如果是这样,怎么样?如果没有,为什么不呢?
您不需要执行任何清理,因为priority_queue持有PathCost
个对象。当它们从队列中删除时,它们的析构函数会根据语言规则自动调用。
在幕后,故事可能会更复杂一些。通常,将项插入priority_queue数据结构将导致动态分配该对象的副本。但是资源分配和解除分配由底层数据结构(默认为std::vector
)处理,因此您不必担心内存管理。据说标准库容器和容器适配器具有值语义。
我不明白的是:top()返回一个引用而不是一个指针。但是我不能在引用上使用delete,可以吗?
priority_queue
被称为拥有它所拥有的元素,因此如果您对其中一个元素进行引用,则无法删除它。实际上,您无法知道是否需要删除它。此外,尽管您可以访问队列中元素的引用,但您不必强制保留对这些元素的引用。您也可以自己制作副本:
const PathCost& pRef = tentativeQ.top(); // take constant reference to top element
PathCost p = tentativeQ.top(); // make copy of last element
在第一种情况下,在通过调用pop()
删除顶部元素后,您必须小心不要使用该引用。