堆栈溢出与我的析构函数

问题描述:

这是我的第一篇文章堆栈溢出。我正在创建一个程序来按字母顺序将文本解析为链接列表,并跟踪每个单词的计数。该程序运行正常(通过罚款我的意思是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; 
    } 
+3

与你的SO无关,你可能会弄清楚为什么你的if(node == NULL)'永远不会*为真。我提到这一点是因为*简化代码*是发现错误的第一步。 –

+3

它是“析构函数”。 – chris

+0

请包括您的模板类的析构函数。我敢打赌,你在里面叫'destroyWord'。为什么你评论一些真正改变语义的代码?我会从一些单元测试开始,从简单的例子到更复杂的例子。 –

我敢打赌:你的析构函数中最有可能调用destroyWord。我们可以看到destroyWord有一个delete nodeD;声明。 nodeDWordList<T>的类型,所以这将导致WordList<T>上的析构函数调用,并且具有delete nodeD;,正如我们所见。有我们的无限递归。

+0

它不是无限的。它最终会在到达最后一个节点时停止。但是调用堆栈的深度是有限的(显然),所以你可以将足够的数据推送到列表中以引起堆栈溢出(事实上,使用智能指针管理的链接列表是微不足道的)。 – WhozCraig

+0

@WhozCraig:你是否暗示我的意思是“无限”字面意思?我不知道我必须解释这一点,但“无限循环”和“无限递归”是理论上的。这意味着你有一个潜在的缺陷,这将导致无限的递归或循环,因为你有无限大的内存和/或无限的时间。 –

+1

我建议当有人说“无限”他们的意思。这里使用的算法不是无限的。它可以*潜在地*通过适当数量的列表数据达到它所参与的运行时间限制。追逐自引用列表节点的路径(this-> next = this)是无限的。这个算法不是。这是错误的;它被窃听;但它不是无限的。 – WhozCraig