释放整个链表,这个算法是否正确?

时间:2012-11-11 06:04:59

标签: c recursion linked-list free

这可能吗?或者会丢失一份名单?因为我无法检查它是否正常工作

void FreeRecurs(struct nodeTag *pFirst)
{
    if(pFirst != NULL)
    {   
            FreeRecurs(pFirst -> pNext);
            free(pFirst);
    }
}

4 个答案:

答案 0 :(得分:6)

这将有效,但在长列表中,您可能会得到堆栈溢出,因为您正在递归很多并且没有使用尾递归。我将转向迭代版本:

  • 当前节点不为NULL:
    • 存储指向下一个节点的指针。
    • 释放当前节点。
    • 使用您在释放之前存储的指针开始处理下一个节点。

答案 1 :(得分:2)

从理论上讲这是可以的,但是你可以通过使其尾递归来改进它:

void FreeRecurs(struct nodeTag *pFirst)
{
    if(pFirst != NULL)
    {   
            struct nodeTag* const next = pFirst->pNext;
            free(pFirst);
            FreeRecurs(next);
    }
}

请注意,FreeRecurs(next)现在是函数中的最后一个语句。编译器会识别出这一点,你的代码运行得更快,不会冒着粉碎堆栈的风险。

除此之外,每当您不确定是否丢失内存时,您可以在valgrind(特别是massif)中运行您的程序,它会告诉您内存是否丢失。

答案 2 :(得分:1)

此算法可行。也就是说,您应该学会使用valgrindgdb之类的工具来准确监控代码中发生的情况,以便判断它是否正常工作。

答案 3 :(得分:1)

我不会使用递归,而是使用类似的东西:

void FreeRecurs(struct nodeTag *pFirst)
{
    struct nodeTag *aux = NULL;
    while (pFirst != NULL)
    {   
        aux = pFirst;
        pFirst = pFirst -> pNext;
        free(aux);
    }
}

递归导致堆栈溢出,实际上最终会变慢,因为每个函数调用都有一个新的调用堆栈。