c++ - 释放指向保留嵌套变量内存地址的结构的指针

标签 c++ pointers memory-leaks nested

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;
}

我有一个具有以下字段的递归结构 ListNode:

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

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

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

最佳答案

这里有几个问题。

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()分别。

根据签名,front() 返回一个引用,如果 T 是一个重对象,这会更有效。

当然,这一切都假设您是出于学术目的而进行的。否则,好吧,使用 std::list 或类似的标准库容器。

关于c++ - 释放指向保留嵌套变量内存地址的结构的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45374096/

相关文章:

c++ - Cygwin g++ 无法将 "fixed"识别为 STD 库的一部分

c++ - 为什么下面的代码会导致模板实例化?

c++ - 源更改后 QML 图像不更新

c - 连续应用两个显式指针转换?

c++ - 从动态分配的解引用指针默认初始化非常量引用函数参数是否会造成内存泄漏?

memory-leaks - Coldfusion.util.Key 内存泄漏 - 结构键问题?

c++ - 检查 IF 语句中的多个 OR 运算符

c - 中序遍历偏离内存中的其他位置

c++ - 比较指向的两个整数值

iphone - 自动释放导致应用程序崩溃