简体   繁体   English

无法理解如何解决此内存泄漏

[英]Failing to understand how to fix this memory leak

I'm creating a small solver that takes three arguments: number of hours, current time and true time. 我正在创建一个使用三个参数的小型求解器:小时数,当前时间和真实时间。

The program itself works fine, but there are memory leaks that I am unable to fix. 该程序本身可以正常工作,但是存在无法修复的内存泄漏。

Code: 码:

Inside my main: 在我的主内:

vector<ClockState> moves = sol.solve(curClock);

solve method: solve方法:

std::vector<Game> Solver<Game>::solve(Game curCfg){
    std::vector<Game> result;
    std::vector<Game> seen;
    std::queue<Game> q;

    q.push(curCfg);
    seen.push_back(curCfg);

    std::vector<Game> moves;

    Game cfg = q.front();
    Game * newCfg = NULL;

    while (q.size() > 0) {

        if (q.front().isEndState()) {
            break;
        }

        cfg = q.front();
        q.pop();

        cfg.getMoves(moves);
        for (unsigned int i = 0; i < moves.size(); i++) {
            if (find(seen.begin(), seen.end(), moves[i]) == seen.end()) {
                newCfg = new Game(cfg);
                moves[i].setPrev(newCfg);
                q.push(moves[i]);
                seen.push_back(moves[i]);
            }
        }
    }

    delete newCfg;

    if(q.empty()){
        return result;
    }

    Game temp(q.front());

    while (true) {
        result.push_back(temp);
        if (temp == curCfg) {
            break;
        }
        temp = temp.prev();
    }
    reverse(result.begin(), result.end());
    return result;
}

And my setPrev method (inside ClockState) 还有我的setPrev方法(在ClockState内部)

void ClockState::setPrev(ClockState *prev) {
    previous = prev;
}

previous is a pointer inside the ClockState class. previous是ClockState类内的指针。

From my understanding I need to delete newCfg and even when I try to do that it still causes a memory leak. 据我了解,我需要删除newCfg ,即使尝试这样做也仍然会导致内存泄漏。

Here is the output from valgrind --leak-check=full ./clock 12 10 3 这是valgrind --leak-check=full ./clock 12 10 3的输出valgrind --leak-check=full ./clock 12 10 3

==16856==
==16856== HEAP SUMMARY:
==16856==     in use at exit: 64 bytes in 4 blocks
==16856==   total heap usage: 28 allocs, 24 frees, 2,095 bytes allocated
==16856==
==16856== 64 (16 direct, 48 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==16856==    at 0x402569A: operator new(unsigned int) (vg_replace_malloc.c:255)
==16856==    by 0x8049AB1: Solver<ClockState>::solve(ClockState) (Solver.h:102)
==16856==    by 0x804964B: main (clock.cpp:106)
==16856==
==16856== LEAK SUMMARY:
==16856==    definitely lost: 16 bytes in 1 blocks
==16856==    indirectly lost: 48 bytes in 3 blocks
==16856==      possibly lost: 0 bytes in 0 blocks
==16856==    still reachable: 0 bytes in 0 blocks
==16856==         suppressed: 0 bytes in 0 blocks
==16856==
==16856== For counts of detected and suppressed errors, rerun with: -v
==16856== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from 6)

Line 102 is newCfg = new Game(cfg); 第102行是newCfg = new Game(cfg);

When Solver returns that vector, I end up printing the results, and directly after that I delete each previous with the following: 当Solver返回该向量时,我最终打印结果,然后在此之后立即删除以下内容:

for(int j = 0; j < moves.size(); j++){
    moves[j].deletePrev();
}

deletePrev() just says delete previous; deletePrev()只是说delete previous;

Appreciate it. 欣赏它。

You create new objects in aloop, but delete only one, which causes your memory leak. 您在aloop中创建新对象,但仅删除其中一个,这会导致内存泄漏。

You need to loop through each move and delete the element pointer to by the previous pointer 您需要遍历每个动作并删除previous指针指向的元素指针

Alternatively, just create only one Game object and delete it when you are done with it (as you are re-creating identical objects many times over) 或者,仅创建一个Game对象并在完成后将其删除(因为您要多次创建相同的对象)

Yet another alternative is to copy the Game object by value (so no new or delete is needed) if you don't want to share the object among many other object 另一个选择是如果您不想在许多其他对象之间共享该对象,则按值复制Game对象(因此不需要newdelete

Another approach is to use some sort of smart pointer (eg from BOOST or use C++11) 另一种方法是使用某种智能指针(例如从BOOST或使用C ++ 11)

this code: 此代码:

Game * newCfg = NULL;
while (q.size() > 0) {

    if (q.front().isEndState()) {
        break;
    }

    cfg = q.front();
    q.pop();
    std::vector<Game> moves;
    cfg.getMoves(moves);
    for (int i = 0; i < moves.size(); i++) {
        if (find(seen.begin(), seen.end(), moves[i]) == seen.end()) {
            newCfg = new Game(cfg);
            moves[i].setPrev(newCfg);
            q.push(moves[i]);
            seen.push_back(moves[i]);
        }
    }
}

delete newCfg;

declares a variable named newCfg that is a pointer to a Game. 声明一个名为newCfg的变量,该变量是一个Game的指针。 However, isnide of the loop, you keep new'ing new instances of a Game class and adding them to the moves container. 但是,在循环过程中,您保留Game类的新实例并将其添加到moves容器中。 you need to 'delete' each instance of Game* that you've added to the moves container. 您需要“删除”已添加到moves容器中的每个Game *实例。

your code above essentially does the same thing as this code: 您上面的代码与该代码基本上具有相同的作用:

int* myInts = NULL;
myInts = new Int[2];
myInts = new Int[5];
delete myInts; // <-- only deletes memory for Int[5],
               // Int[2] memory is dangling in no-mans-land

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM