堆栈溢出与我的析构函数
这是我的第一篇文章堆栈溢出。我正在创建一个程序来按字母顺序将文本解析为链接列表,并跟踪每个单词的计数。该程序运行正常(通过罚款我的意思是15分钟,这显然很慢,并没有使用强大的数据结构),直到我的程序返回并尝试解构动态分配的内存。有人可以帮助确定哪些代码可能需要调整以避免溢出堆栈?堆栈溢出与我的析构函数
template <class T>
void WordList<T>::destroyWord(WordList<T> *node)
{
WordList<T>* nodeD = NULL;
for(; node != NULL;)
{
if(node == NULL)
return;
else if(node->mNext != NULL)
{
nodeD = node;
node = node->mNext;
}
else
{
// We have found the node to delete.
//destroyWord(node->mNext);
if(node->mNext == NULL)
{
if(nodeD != NULL)
{
nodeD->mNext = NULL;
delete nodeD;
}
else
{
node = NULL;
}
}
nodeD = NULL;
}
}
// **********************************
// Delete the node at the root.
//delete node;
return;
}
这里是我修改后的代码,谢谢你们....
template <class T>
void WordList<T>::destroyWord(WordList<T> *node)
{
node = node->mRootNode->mNext;
static WordList<T>* ptr = node;
for(; node != NULL && node->mNext != NULL;)
{
ptr = node->mNext;
delete (char*)node;
node = ptr;
}
delete (char*)ptr;
}
我敢打赌:你的析构函数中最有可能调用destroyWord
。我们可以看到destroyWord
有一个delete nodeD;
声明。 nodeD
是WordList<T>
的类型,所以这将导致WordList<T>
上的析构函数调用,并且具有delete nodeD;
,正如我们所见。有我们的无限递归。
它不是无限的。它最终会在到达最后一个节点时停止。但是调用堆栈的深度是有限的(显然),所以你可以将足够的数据推送到列表中以引起堆栈溢出(事实上,使用智能指针管理的链接列表是微不足道的)。 – WhozCraig
@WhozCraig:你是否暗示我的意思是“无限”字面意思?我不知道我必须解释这一点,但“无限循环”和“无限递归”是理论上的。这意味着你有一个潜在的缺陷,这将导致无限的递归或循环,因为你有无限大的内存和/或无限的时间。 –
我建议当有人说“无限”他们的意思。这里使用的算法不是无限的。它可以*潜在地*通过适当数量的列表数据达到它所参与的运行时间限制。追逐自引用列表节点的路径(this-> next = this)是无限的。这个算法不是。这是错误的;它被窃听;但它不是无限的。 – WhozCraig
与你的SO无关,你可能会弄清楚为什么你的if(node == NULL)'永远不会*为真。我提到这一点是因为*简化代码*是发现错误的第一步。 –
它是“析构函数”。 – chris
请包括您的模板类的析构函数。我敢打赌,你在里面叫'destroyWord'。为什么你评论一些真正改变语义的代码?我会从一些单元测试开始,从简单的例子到更复杂的例子。 –