代码之家  ›  专栏  ›  技术社区  ›  Kirill Korolev

将指针释放到保留嵌套变量内存地址的结构

  •  0
  • Kirill Korolev  · 技术社区  · 7 年前
    template<typename T>
    T& List<T>::popFront()
    {
        if (head == NULL)
            throw std::underflow_error("List error: no head node available\n");
        if (tail == head)
            tail = NULL;
        T item = head->item;
        head = head->next;
        return item;
    }
    

    template <typename T>
    struct ListNode {
        T item;
        ListNode* next;
        ...
    }
    

    问题是,我想在popFront过程之后取消分配头节点,但由于所有嵌套节点都间接指向同一地址,它们的地址也会从堆中消失。现在,正如你们在上面看到的,我只是把一个头节点的指针地址改成下一个,我认为这会导致内存泄漏。

    我不排除我对这种方法和我的假设是绝对错误的。如果确实需要取消分配,请考虑执行此类任务的最有效方式。

    2 回复  |  直到 7 年前
        1
  •  2
  •   Ramon    7 年前

    这里有几个问题。

    template<typename T>
    T& List<T>::popFront()
    {
        if (head == NULL)
            throw std::underflow_error("List error: no head node available\n");
        if (tail == head)
            tail = NULL;
        T item = head->item;
        head = head->next; //Memory leak, you just lost your only pointer to the head item
        return item; //Returning reference to stack variable, undefined behavior
    }
    

    我建议您将签名更改为按值返回,这样您就可以返回一个本地元素并在堆中取消分配元素。

    template<typename T>
    T List<T>::popFront()
    {
        if (head == NULL)
            throw std::underflow_error("List error: no head node available\n");
        if (tail == head)
            tail = NULL;
        T item = head->item;
        ListNode* old_head = head; //keep this for deallocation
        head = head->next;
        delete old_head; //Deallocate the old head
        return item; //Return by value
    }
    

    当然,你可以采取 std::list front() pop_front() 分别地

    前() T 是一个很重的物体。

    当然,这都是假设你是出于学术目的。否则,好吧,使用 标准::列表 或类似的标准库容器。

        2
  •  1
  •   patatahooligan    7 年前

    当你弹出头部时,在删除它之前,抓住下一个指针并使其成为头部。

    template<typename T>
    T List<T>::popFront()
    {
        if (head == NULL)
            throw std::underflow_error("List error: no head node available");
        if (tail == head)
            tail = NULL;
        T item = head->item;
        ListNode *next = head->next;    // Grab next
        delete head;                    // Now it is safe to delete head
        head = next;                    // Head now points to next
        return item;
    }
    

    NULL 当只有一个节点时?

    编辑:刚刚注意到。你不应该返回对 Item ListNode ListNode* 而不是删除它,但这可能不是你想要的 List