Recursion 较大尝试的递归释放

Recursion 较大尝试的递归释放,recursion,memory,memory-management,segmentation-fault,trie,Recursion,Memory,Memory Management,Segmentation Fault,Trie,我已经编写了一个基本函数,用于在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]); }

我已经编写了一个基本函数,用于在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);
}
//根指针在初始调用中作为arg传递
无效销毁(节点*trav)
{
对于(int i=0;ichildren[i])
{
销毁(trav->儿童[i]);
}
}
免费(trav);
}
对于任何较小的字典文件,该函数似乎都可以很好地工作。程序成功加载和卸载的最大文件包含134480个字

但是,在释放较大的trie时,它会产生分段错误。导致分段错误的较大文件包含506915个字

Valgrind生成的错误消息指出:“大小为8的无效读取”,然后是几个回溯,最后是;“地址不是堆栈、malloc或(最近)空闲”

这可能是什么原因造成的

这可能是什么原因造成的

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

但是,如果您的trie极不平衡,则可能会出现堆栈溢出

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


或者您可以在GDB下运行程序,并检查报告
SIGSEGV
的指令。如果是
调用
推送
,或另一种形式的“移动到堆栈”,堆栈溢出也很可能发生。

我的资源限制已设置为最大值。如何使用GDB来识别分段错误的原因?它只是说,当我通过GDB运行程序时,程序收到了信号SIGSEGV。@GabrielSaul
GDB--args/path/to/exe arg1…
。你可能还想读一读作为介绍——它会很好地打断你。非常抱歉。结果是我的一个缓冲区变量不够大,无法处理某个字符串。谢谢你的资源@GabrielSaul您应该考虑使用address sanitizer()构建您的程序——很可能这并不是这种类型的唯一错误,即使是,使用
-fsanize=address
进行测试也是一个非常好的习惯。