2014-12-06 60 views
0

我正在使用树结构。C++调试segfault,运行良好,无需调试

树中的所有节点都保存在列表中,每个节点的子节点保存在TreeNode对象内的TreeNode指针列表中。

这应该递归地擦除从给定节点开始的子树。

它从“节点”列表中删除TreeNode对象本身,然后删除子列表中的指针。

它工作正常,但是当我在IDE中使用内置的调试器时,它会在第一次使用(* i)调用destroySubtree时发生段错误。当我正常运行程序时它不会发生段错误,并执行它应该执行的操作。 但这意味着我不能在程序中使用调试器进行其他任何操作。 起初我以为它有什么做我该怎么办实际的擦除,但它出现segfaults在destroySubtree的第一个递归调用 - 它的任何擦除之前...

void Tree::destroySubtree(TreeNode* node) 
{ 
    if(node->children.size() == 0) 
     return; 

    list<TreeNode*>::iterator i; 

    for(i = node->children.begin(); i != node->children.end(); i++) 
    { 
     destroySubtree((*i)); //segfaults here, only when debugging 

     list<TreeNode>::iterator j; 
     for(j = nodes.begin(); j != nodes.end(); j++) 
     { 
      if((j)->nId == (*i)->nId) 
      { 
       nodes.erase(j); 
       break; 
      } 
     } 
     node->children.erase(i); 
     i--; 
    } 
} 

有谁知道为什么会这样,以及我如何避免段错误?

它失败了,stl_list.h:768如果有帮助?

+0

'node-> children.erase(i);我 - ;'看起来不正确。也许'我= node-> children.erase(i);' – greatwolf 2014-12-06 01:21:40

+0

如果您想通过迭代器擦除,请按相反顺序执行。我很懒 - 我只是一直擦除第一个孩子,直到没有人。 – Mike 2014-12-06 01:32:31

回答

0

在您致电node->children->erase(i)后,i是无效的迭代器。之后的任何操作都是未定义行为的原因。你需要使用的是:

i = node->children.erase(i); 

并删除递增和递减迭代器的代码。

for(i = node->children.begin(); i != node->children.end(); /* ++i Don't need this*/) 
{ 
    destroySubtree((*i)); //segfaults here, only when debugging 

    list<TreeNode>::iterator j; 
    for(j = nodes.begin(); j != nodes.end(); j++) 
    { 
     if((j)->nId == (*i)->nId) 
     { 
      nodes.erase(j); 
      break; 
     } 
    } 
    i = node->children.erase(i); 
    // i--; Don't need this. 
} 
相关问题