当我调用解构器时,这会导致内存泄漏吗

Does this cause memory leak when I call the deconstructor?

本文关键字:内存 泄漏 调用      更新时间:2023-10-16

我必须为我的Uni类做一个数据结构项目,该项目将实现一个带有链表的堆栈;简单的东西。在代码方面,我们得到了一些帮助,向我们展示了实现这种结构的正确方法。

堆栈类别:

class Stack
{
public:
    Stack(void)
    {
        top = NULL;     // Initialises defualt top node pointer.
    }
    ~Stack(void)
    {
        while (NodePop() != NULL){}
    }
    void Push(int value)    // Pushes a new node onto the stack.
    {
        Node* temp = new Node(value, top);  // Creates a temporary node with a value and makes it 
                                            // point to the top node as the next node in the stack.
        top = temp;                         // Temporary node becomes the top node in the stack.
    }
    Node* NodePop(void)
    {
        /* Remove top node from the stack */
        Node* temp = top;                       // Creates a temporary node to return, sets it to top node.
        if (top != NULL) top = top->getNext();  // Points the stacks top node to the next node in the list.
        return temp;                            // Returns a pointer to the popped node still in the heap.
    }
    int Pop(void)       // Pops the top node off of the stack. Returns the nodes value.
    {
        Node* temp = NodePop();     
        int valueReturn = 0;
        /* Sets the return value */
        if (temp != NULL)
        {
            valueReturn = temp->getVal();   // Set return value to the nodes value if there is a node left.
        }
        else
        {
            throw "Stack Empty";            // Throws exception if temp is NULL and stack is empty. 
        }
        delete temp;            // Deletes the node entirely from the heap.
        return valueReturn;
    }
private:
    Node* top;
};

节点类别:

class Node
{
public:
    Node(int value, Node* nextptr = NULL, Node* prevptr = NULL, int currentpriority = 0)
    {
        /* Set initial variables for the node at creation */
        this->value = value;
        this->next = nextptr;
        this->prev = prevptr;
        this->priority = currentpriority;
    }
    // bunch of getters and setters...
private:
    Node* next;     // Pointer to the next node.
    Node* prev;     // Pointer to the previous node.
    int priority;   // Stores the node priority as a number 0-9.
    int value;      // Stores the node value for printing.
};

我们不能更改任何类结构(我也很烦恼,NodePop()应该是私有的,但w/e)。

因此,NodePop()本质上从列表中删除了顶部节点,但没有删除它;它从链表中删除所有对它的引用,但从不从堆中删除它,它只是在Pop()中从堆中被删除。一切都很好(除了可以公开调用NodePop(),但我不允许将其设为私有)。但当我调用析构函数时,必须使用NodePop(),而不是Pop(。

这是否意味着当NodePop()从析构函数中运行时,节点永远不会从堆中删除

如果是,我该如何删除它们,因为它将运行nodePop(),如果我在一段时间内有它,do while,或者如果语句条件是总是有一个节点未删除

查看有问题的代码

~Stack(void)
{
    while (NodePop() != NULL){}
}
Node* NodePop(void)
{
    /* Remove top node from the stack */
    Node* temp = top;                       // Creates a temporary node to return, sets it to top node.
    if (top != NULL) top = top->getNext();  // Points the stacks top node to the next node in the list.
    return temp;                            // Returns a pointer to the popped node still in the heap.
}

析构函数调用NodePop(),直到该函数返回NULL为止。让我们看看NodePop()的作用。代码中的注释声称它是Creates a temporary node to return这不是真的。它创建一个指向节点(Node*)的指针,并将该指针设置为指向与top相同的位置。如果top不为null,它会将top设置为指向top的下一个节点。它返回temp是指向最初的顶部节点的指针。

在任何时候都不会释放与任何节点关联的内存,所以确实存在内存泄漏。

您可以通过删除析构函数中遇到的每个非NULL的Node*来修复泄漏。

事实上,节点没有被删除,这段代码会泄漏。你可以使用像Valgrind这样的工具来验证这一点。

我会把while改成类似while (Node *N = NodePop()) delete N;

仅供参考,这段代码绝对不是惯用的C++11。这基本上是一个写得很差的C,我希望能在其中找到更多的错误。你的老师应该因为这样展示C++11而受到惩罚:-)