C ++ отладка segfault, работает без отладки

0

Я работаю с древовидной структурой.

Все узлы в дереве хранятся в списке, а дочерние элементы каждого узла хранятся в списке указателей TreeNode внутри объекта TreeNode.

Это должно рекурсивно стирать поддерево, начиная с заданного узла.

Он стирает сам объект TreeNode из списка "узлы", а затем указатель в списке "Дети".

Он отлично работает, однако, когда я использую встроенный отладчик в среде IDE, он сначала отключается, когда destroySubtree вызывается с (* i). Это не segfault, когда я запускаю программу нормально и делает то, что должен. Но это означает, что я не могу использовать отладчик для чего-либо еще в программе. Сначала я подумал, что это имеет какое-то отношение к тому, как я действительно стираю, но он преследует ПЕРВЫЙ рекурсивный вызов 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--;
    }
}

Кто-нибудь знает, почему это происходит, и как я могу избежать segfault?

Это не удается, stl_list.h: 768, если это помогает?

  • 0
    node->children.erase(i); i--; не выглядит правильно. Может быть, i = node->children.erase(i);
  • 0
    Если вы хотите удалить через итератор, делайте это в обратном порядке. Я ленивый - я просто стираю первого ребенка, пока его нет.
Теги:
list
debugging

1 ответ

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.
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню