较大尝试的递归释放

Recursive deallocation of larger tries

我已经在 C:

中编写了一个用于递归释放 trie 数据结构的基本函数
// Root pointer is passed as arg in initial call
void destroy(node *trav)
{
    for (int i = 0; i < N; i++)
    {
        if (trav->children[i])
        {
            destroy(trav->children[i]);
        }
    }

    free(trav);
}

这个函数似乎可以完美地处理任何较小的字典文件。程序成功加载和卸载的最大文件包含134,480个单词。

但是,它在释放更大的 trie 时会产生分段错误。导致分段错误的较大文件包含 506,915 个单词。

Valgrind 生成的错误消息指出:"Invalid read of size 8" 后跟几个回溯,最后; "Address is not stack'd, malloc'd or (recently) free'd".

可能是什么原因造成的?

What might be causing this?

堆栈溢出可能是造成这种情况的原因,尽管这似乎不太可能:几乎没有局部变量,因此每个帧可能只消耗 32 个字节的堆栈,这将允许递归 8M/32 == 262144 层深Linux 默认 8MiB 堆栈。

但是,如果你的 trie 极度不平衡,堆栈溢出是可能的。

您可以尝试 ulimit -s unlimited 看看是否可以解决问题。

或者您可以 运行 您的程序在 GDB 下,并检查报告 SIGSEGV 的指令。如果是CALLPUSH或者其他形式的"move to stack",也很有可能出现栈溢出。