较大尝试的递归释放
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
的指令。如果是CALL
、PUSH
或者其他形式的"move to stack",也很有可能出现栈溢出。
我已经在 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
的指令。如果是CALL
、PUSH
或者其他形式的"move to stack",也很有可能出现栈溢出。