Я работаю с древовидной структурой.
Все узлы в дереве хранятся в списке, а дочерние элементы каждого узла хранятся в списке указателей 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, если это помогает?
После вызова 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.
}
node->children.erase(i); i--;
не выглядит правильно. Может быть,i = node->children.erase(i);