Why is my program leaking memory? (working with trees in C++)

允我心安 提交于 2021-02-11 13:47:46

问题


I'm creating a tree of dynamic objects. The Node class has a vector to store the child nodes, among the other class variables:

std::vector<Node*> child;

The class destructor deletes all the dynamically allocated class variables, and then deletes the child nodes:

~Node() {
    //Deleting the other variables
                .
                .
                .

    //Deleting the child nodes
    for(int i = 0; i < child.size(); i++) {
        delete child[i];
    }
}

My class has a method that creates a tree of a given height, in which the current node is the root node:

void createTree(int height) {
    if(height == 0) {
        return;
    }
    for(int i = 0; i < numberOfChildNodes; i++) {
        child.push_back(new Node());
        child[i]->createTree(height - 1);
    }
}

This class has another method where I create a tree with height = 3, then I delete the entire tree and create another one with height = 4, then I delete the entire tree and create one with height = 5, and so on, until a memory limit is reached:

void highestTreePossible() {
    int i, height = 3;
    struct sysinfo memInfo;
    while(true) {
        createTree(height);
        sysinfo (&memInfo);
        if(memInfo.freeram > limit) {
            std::cout << "Highest tree possible: height = " << height;
            break;
        }
        for(i = 0; i < child.size(); i++) {
            delete child[i];
        }
        child.clear();
        height++;
    }
    for(i = 0; i < child.size(); i++) {
        delete child[i];
    }
    child.clear();
}

The problem is, when I check the memory after running the method highestTreePossible(), there's a lot of memory allocated, which isn't supposed to happen, because I deleted everything. Why is my code leaking memory?


回答1:


It's not leaking; you're not using a valid test for this kind of thing. Modern operating systems have complex memory management, and you may observe a process "holding on" to more memory than you think it needs at any given time. Rest assured, it is available to the rest of the system when required.

If you're concerned about memory, you need to observe a constant, consistent rise in consumption for your process over a significant period of time, or hook into the actual allocators used by your program itself. A great way to do this is using a diagnostic tool like massif, which ships with Valgrind (if you're on a compatible system). There are some great ways to visualise that.




回答2:


If you're on a Linux system, you can try to use valgrind to reliably check if your code has any memory leaks.

e.g.  $valgrind --leak-check=full ./node_test  

So to answer the question "Why is my code leaking memory?"

There is no memory leak in your code as I tested/checked it with valgrind report (e.g. "All heap blocks were freed -- no leaks are possible"). However, I seem to notice some problem in the line containing the exit condition if(memInfo.freeram > limit) since memInfo.freeram value is expected to be decreasing as the tree grows. And that your goal is to keep the tree growing (hence memInfo.freeram will also be shrinking) "until a memory limit is reached" as you've mentioned above or "until the memInfo.freeram falls below a certain limit" as I rephrased it.

So I expect that the correct exit condition should supposedly be the opposite if(memInfo.freeram < limit).

Hope this helps.

PS. It's also a good practice to use smart pointers (e.g. std::unique_ptr, std::shared_ptr) to avoid memory leaks.



来源:https://stackoverflow.com/questions/61892960/why-is-my-program-leaking-memory-working-with-trees-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!