Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
找不到小内存泄漏的源 我创建了一个程序,它可以用蛮力回溯算法解决C++中数独的难题,但是在分析Valgnd内存使用后,我发现它有一个小漏洞。我注意到一个GCC错误,它导致1个丢失的空闲字节和72704个仍然可以访问的字节_C++_C++11_Valgrind_Heap Memory - Fatal编程技术网

找不到小内存泄漏的源 我创建了一个程序,它可以用蛮力回溯算法解决C++中数独的难题,但是在分析Valgnd内存使用后,我发现它有一个小漏洞。我注意到一个GCC错误,它导致1个丢失的空闲字节和72704个仍然可以访问的字节

找不到小内存泄漏的源 我创建了一个程序,它可以用蛮力回溯算法解决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

似乎我缺少了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::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;
    }
}