找不到小内存泄漏的源 我创建了一个程序,它可以用蛮力回溯算法解决C++中数独的难题,但是在分析Valgnd内存使用后,我发现它有一个小漏洞。我注意到一个GCC错误,它导致1个丢失的空闲字节和72704个仍然可以访问的字节
似乎我缺少了903个找不到小内存泄漏的源 我创建了一个程序,它可以用蛮力回溯算法解决C++中数独的难题,但是在分析Valgnd内存使用后,我发现它有一个小漏洞。我注意到一个GCC错误,它导致1个丢失的空闲字节和72704个仍然可以访问的字节,c++,c++11,valgrind,heap-memory,C++,C++11,Valgrind,Heap Memory,似乎我缺少了903个free()/delete/delete[]调用,这些调用占用了大约100KB的内存 有人知道是什么导致内存泄漏以及我如何修复它吗 Backtracker.cpp #include "Backtracker.h" /** * Clears all dynamic memory in the list. * @param lst: the pointer to the list to be cleared */ static void clearList(std::li
free()
/delete
/delete[]
调用,这些调用占用了大约100KB的内存
有人知道是什么导致内存泄漏以及我如何修复它吗
Backtracker.cpp
#include "Backtracker.h"
/**
* Clears all dynamic memory in the list.
* @param lst: the pointer to the list to be cleared
*/
static void clearList(std::list<Grid*> *lst) {
std::list<Grid*>::iterator it;
for (unsigned int i = 0; i < lst->size(); i++) {
it = lst->begin();
std::advance(it, i);
delete *it;
}
delete lst;
}
/**
* Solves the sudoku puzzle or returns a null if there is no solution.
* @param g: a pointer to the starting grid
* @return: a pointer to the solution
*/
Grid* solve(Grid *g) {
if (g->isGoal()) {
return g;
}
std::list<Grid*> *successors = g->getSuccessors();
std::list<Grid*>::iterator it;
for (unsigned int i = 0; i < successors->size(); i++) {
it = successors->begin();
std::advance(it, i);
if ((*it)->isValid()) {
Grid *solution = solve(*it);
if (solution != nullptr) {
solution = solution->copyGrid();
clearList(successors);
return solution;
}
}
}
clearList(successors);
return nullptr;
}`
不确定这是你的问题,但是。。。根据valgrind的说法,这个问题与
Grid::copyGrid()
中分配的内存有关,因此以下新
Grid* Grid::copyGrid() {
Grid *copy = new Grid();
// ...
return copy;
}
我怀疑问题在solve()
中
观察solve()
solution = solution->copyGrid();
因此,分配的(new
)值将丢失由
Grid *solution = solve(*it);
它来自solve()
,所以它被分配了
我的意思是:删除由solve()
返回的值
我想你应该写这样的东西
if ((*it)->isValid()) {
Grid *solution = solve(*it);
if (solution != nullptr) {
Grid *retSol = solution->copyGrid();
clearList(successors);
delete solution;
return retSol;
}
}
--编辑--
OP的答案是:
我刚刚试过这个,但是它只会导致分割错误。删除删除解决方案;行修复了分段错误,但内存泄漏仍然存在
我明白了。。。
这里的问题是(如果我没有错的话)solve()
也可以返回接收到的值
Grid* solve(Grid *g) {
if (g->isGoal()) {
return g;
}
嗯
因此,如果与*it
不同,您只能将其删除
我不喜欢,但我提议
if ((*it)->isValid()) {
Grid *solution = solve(*it);
if (solution != nullptr) {
Grid *retSol = solution->copyGrid();
clearList(successors);
if ( solution != *it )
delete solution;
return retSol;
}
}
这真的重要吗?当应用程序终止时,内核将释放进程分配的所有内存。事实上实际上,自己释放内存可能比泄漏内存并让内核清理要慢;-)这不是那么重要,我只是想了解是什么原因造成的,因为我正试图自己学习C++。@ AnthonyPalumbo,你不应该这么多使用原始指针。STL提供了std::unique_ptr
和std::shared_ptr
,以及std::vector
作为通用容器(以及许多其他容器)。使用它们@BenSteffan没有迭代器无效。他们没有改变列表,只是将每个元素传递给delete
。但是他们在做一些愚蠢的事情。从开头开始,对每个元素执行i
步骤,将线性迭代转化为二次运算。我会使用一个循环:for(Grid*ptr:*lst){delete ptr;}
我刚刚尝试过这个,但它只会导致分段错误。删除删除解决方案;行修复了分段错误,但内存泄漏仍然存在。解决方案不需要显式删除,因为原始解决方案在clearList函数期间被删除,这就是为什么在清除列表之前需要复制解决方案的原因。@AnthonyPalumbo-我明白了。。。修改答案
if ((*it)->isValid()) {
Grid *solution = solve(*it);
if (solution != nullptr) {
Grid *retSol = solution->copyGrid();
clearList(successors);
delete solution;
return retSol;
}
}
Grid* solve(Grid *g) {
if (g->isGoal()) {
return g;
}
if ((*it)->isValid()) {
Grid *solution = solve(*it);
if (solution != nullptr) {
Grid *retSol = solution->copyGrid();
clearList(successors);
if ( solution != *it )
delete solution;
return retSol;
}
}