Memory 找不到内存泄漏
我花了上周的时间试图找出这个内存泄漏,我在这一点上绝望。我很高兴能得到任何帮助 我有一个类求解器,它在方法solve的每次迭代中创建类PartialGraph的实例(执行深度优先搜索)。在每次迭代中,部分图都应该复制到堆栈中,并销毁 解算器Memory 找不到内存泄漏,memory,valgrind,memory-leaks,Memory,Valgrind,Memory Leaks,我花了上周的时间试图找出这个内存泄漏,我在这一点上绝望。我很高兴能得到任何帮助 我有一个类求解器,它在方法solve的每次迭代中创建类PartialGraph的实例(执行深度优先搜索)。在每次迭代中,部分图都应该复制到堆栈中,并销毁 解算器 class Solver { public: Solver(Graph pg); PartialGraph solve(PartialGraph p, int bestest); Graph pg; stack<PartialGraph> st
class Solver {
public:
Solver(Graph pg);
PartialGraph solve(PartialGraph p, int bestest);
Graph pg;
stack<PartialGraph> stackk;
bool isSpanningTree(PartialGraph* p);
Solver(const Solver& orig);
~Solver();
它运行得很好,但当输入数据太大时,我的alloc就坏了。Valgrind说我在PartialGraph.cpp的第53行泄漏,但我几乎可以肯定所有实例都在第101行或迭代的早期被销毁
(244,944 direct, 116 indirect) bytes in 5,103 blocks are definitely lost in
at 0x4C2AA37: operator new(unsigned long)
(in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x4039F6: PartialGraph::addEdge(Edge) (PartialGraph.cpp:107)
by 0x404197: Solver::solve(PartialGraph, int) (Solver.cpp:53)
by 0x4016BA: main (main.cpp:35)
LEAK SUMMARY:
definitely lost: 246,305 bytes in 5,136 blocks
indirectly lost: 1,364 bytes in 12 blocks
我甚至制作了一个实例计数器,似乎我销毁了所有的实例。正如我所说的,我真的很绝望,希望能得到帮助。简而言之,你永远不应该直接给析构函数打电话。改为使用
delete
,以便在您拥有pnew->~PartialGraph()的任何地方
,您应该有删除pnew代码>。一般来说,每个新
都应该在某个地方有一个相应的delete
。只是要小心,这个规则有一些诡计,因为多个删除可能映射到一个新的,反之亦然
我在查看代码时发现的额外漏洞:
- 文章中的第一行可执行代码:
this->pg=*新图形(orig.pg)代码>。另一条一般规则:如果您的代码执行了*new Foo(…)
,那么您可能正在创建泄漏(并且可能为自己创建了不必要的工作)。在这种情况下,this->pg=orig.pg
应该可以正常工作。您当前的代码将orig.pg复制到一个新分配的对象中,然后将新创建的对象复制到这个->pg中,这将导致两个复制操作。这个->pg=orig.pg只是一个副本
- 前几行PartialGraph::operator=()。复制构造函数、赋值运算符和析构函数可能很难正确使用。在所有构造函数中,您都可以创建新的节点和边,并且在析构函数中有匹配的删除,所以这没关系。但在执行赋值运算符时,会覆盖指向现有数组的指针,但不会删除它们。在创建新阵列之前,需要删除现有阵列
最后,yikes。我知道为StackOverflow格式化代码可能会很痛苦,但尝试在Solver::solve()中读取代码会非常痛苦,因为缩进与代码结构不匹配。当我看这篇文章时,有23个观点,没有回应。有23个人对解决你的问题感兴趣,但可能会因为格式问题而感到不快。如果你花额外的23分钟格式化代码,而这为每个人节省了超过一分钟的时间,你就可以为整个宇宙节省一些时间(除了可能更快地得到答案之外)。这段代码非常难读。您应该重新格式化它,以便从这里获得更好的结果。希望这比原来更好!它可以工作谢谢你我猜对了调用析构函数直接导致成员变量不能从堆中释放吗?调用析构函数允许对象执行它需要执行的任何内部清理,但不会释放对象本身。
PartialGraph::PartialGraph(int nodeNumber,int edgeNumber) {
nodeCount=nodeNumber;
edgeCount=0;
nodes=new int[nodeCount];
edges=new Edge[0];
rightestEdge=-1;
generatedNodes=0;
addedEdges=0;
for(int i=0;i<nodeCount;i++){
this->nodes[i]=0;
}
maxDegree=0;
}
PartialGraph::PartialGraph(const PartialGraph& orig){
this->nodes=new int[orig.nodeCount];
edges=new Edge[orig.edgeCount];
this->nodeCount=orig.nodeCount;
this->rightestEdge=orig.rightestEdge;
this->edgeCount=orig.edgeCount;
this->maxDegree=orig.maxDegree;
this->addedEdges=orig.addedEdges;
this->generatedNodes=orig.generatedNodes;
for(int i=0;i<this->nodeCount;i++){
this->nodes[i]=orig.nodes[i];
}
for(int i=0;i<this->edgeCount;i++){
this->edges[i]=orig.edges[i];
}
}
PartialGraph::PartialGraph(){
}
PartialGraph::PartialGraph(const PartialGraph& orig, int i){
this->nodes=new int[orig.nodeCount];
edges=new Edge[orig.edgeCount+1];
this->nodeCount=orig.nodeCount;
this->rightestEdge=orig.rightestEdge;
this->edgeCount=orig.edgeCount;
this->maxDegree=orig.maxDegree;
this->addedEdges=orig.addedEdges;
this->generatedNodes=orig.generatedNodes;
for(int i=0;i<this->nodeCount;i++){
this->nodes[i]=orig.nodes[i];
}
for(int i=0;i<this->edgeCount;i++){
this->edges[i]=orig.edges[i];
}
}
PartialGraph &PartialGraph::operator =(const PartialGraph &orig){
nodes=new int[orig.nodeCount];
edges=new Edge[orig.edgeCount];
this->nodeCount=orig.nodeCount;
this->rightestEdge=orig.rightestEdge;
this->edgeCount=orig.edgeCount;
this->maxDegree=orig.maxDegree;
this->addedEdges=orig.addedEdges;
this->generatedNodes=orig.generatedNodes;
for(int i=0;i<this->nodeCount;i++){
this->nodes[i]=orig.nodes[i];
}
for(int i=0;i<this->edgeCount;i++){
this->edges[i]=orig.edges[i];
}
}
PartialGraph* PartialGraph::addEdge(Edge e){
PartialGraph* npg=new PartialGraph(*this, 1);
npg->edges[this->edgeCount]=e;
npg->addedEdges++;
npg->edgeCount++;
if(e.edgeNumber>npg->rightestEdge){npg->rightestEdge=e.edgeNumber;}
npg->nodes[e.node1]=npg->nodes[e.node1]+1;
npg->nodes[e.node2]=npg->nodes[e.node2]+1;
if(npg->nodes[e.node1]>npg->maxDegree){npg->maxDegree=npg->nodes[e.node1];}
if(npg->nodes[e.node2]>npg->maxDegree){npg->maxDegree=npg->nodes[e.node2];}
if(npg->nodes[e.node1]==1){npg->generatedNodes++;}
if(npg->nodes[e.node2]==1){npg->generatedNodes++;}
return npg;
}
PartialGraph:: ~PartialGraph() //destructor
{
delete [] nodes;
delete [] edges;
};
class PartialGraph {
public:
PartialGraph(int nodeCount,int edgeCount);
PartialGraph* addEdge(Edge e);
PartialGraph(const PartialGraph& orig);
PartialGraph();
~PartialGraph();
static int counter;
PartialGraph(const PartialGraph& orig, int i);
void toString();
int nodeCount;
int edgeCount;
int generatedNodes;
int *nodes;
Edge *edges;
int maxDegree;
int rightestEdge;
int addedEdges;
PartialGraph &operator =(const PartialGraph &other); // Assn. operator
};
(244,944 direct, 116 indirect) bytes in 5,103 blocks are definitely lost in
at 0x4C2AA37: operator new(unsigned long)
(in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x4039F6: PartialGraph::addEdge(Edge) (PartialGraph.cpp:107)
by 0x404197: Solver::solve(PartialGraph, int) (Solver.cpp:53)
by 0x4016BA: main (main.cpp:35)
LEAK SUMMARY:
definitely lost: 246,305 bytes in 5,136 blocks
indirectly lost: 1,364 bytes in 12 blocks