Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.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++ 当我调用解构器时,这是否会导致内存泄漏?_C++ - Fatal编程技术网

C++ 当我调用解构器时,这是否会导致内存泄漏?

C++ 当我调用解构器时,这是否会导致内存泄漏?,c++,C++,我有一个数据结构项目,我必须为我的Uni类做,这是实现一个带有链表的堆栈;简单的东西。我们得到了一些代码方面的帮助,向我们展示了实现这种结构的正确方法 堆栈类: class Stack { public: Stack(void) { top = NULL; // Initialises defualt top node pointer. } ~Stack(void) { while (NodePop() != NU

我有一个数据结构项目,我必须为我的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()

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


如果是这样,我将如何删除它们,因为它将运行nodePop(),如果我在一段时间内有它,则执行while,或者如果语句条件是这样,则始终有一个节点未删除?

确实,节点未被删除,并且此代码将泄漏。您可以使用Valgrind之类的工具来验证这一点

我将
while
更改为
while(Node*N=NodePop())delete N


仅供参考,此代码绝对不是惯用的C++11。它基本上是写得很糟糕的C语言,我希望能在其中发现更多的bug。你的老师应该因为像这样展示C++11而受到惩罚:-)

看看有问题的代码

~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()的作用。代码中的注释声称它
创建了一个临时节点以返回不正确的
。它创建一个指向节点(节点*)的指针,并将该指针设置为指向
top
所指向的位置。如果
top
不为空,它将
top
设置为指向top的下一个节点。它返回
temp
,这是一个指向最初顶部节点的指针

在任何情况下都不会释放与任何节点关联的内存,因此存在内存泄漏


您可以通过删除析构函数中不为NULL的每个节点*来修复漏洞。

感谢您的回答,我不知道您可以在while循环条件中创建变量,但我还是编程新手。不用担心。我可以推荐这本书给新C++程序员:——由C++发明者制作,它涵盖了现代C++设计。你所给的代码有很多错误,内存泄漏是什么?还是一千?很遗憾,在大学里,作为C++的例子,这是一个耻辱。Stroustrup在他的主旨中提到了这个问题,老师教坏C作为C++的介绍。我会对自己和你自己说一句话,然后写一张便条,问这是不是叫POP而不是NoDopp,因为这样会漏掉。谢谢你的回答。我的代码中的注释很糟糕,在我完成之前,我仍然需要重新做一些注释,我知道这是一个指针。