2015-07-05 6 views
0

Я работаю с деревьями для практических целей. Точно Деревья бинарного поиска в настоящее время. У меня есть класс Tree, который я использую для решения проблем BST. Итак, я сталкиваюсь с проблемой tp, которая преобразует данное дерево (BST) в Doubly-связанный список.Деструктор, вызывающий ошибку времени выполнения

Я могу успешно преобразовать дерево в DLL. Но проблема в том, что я звоню destructor. Поскольку я выделяю память узлам моего дерева, я также хочу освободить память. Это деструктор Tree класса ::

~Tree() { 
     delete root; 
     root = NULL; 
    } 

И это деструктор Node класса ::

~Node() { 
     delete left; 
     delete right; 
     left = NULL; 
     right = NULL; 
    } 

Таким образом, программа падает в конце концов! К моему пониманию, поскольку деструкторы, которые я написал, рекурсивно удаляют все узлы дерева, а когда дерево преобразуется в DLL, левые и правые указатели действительно указывают друг на друга, поэтому во время вызова деструктора , деструктор пытается удалить узел, который уже был удален, и что указатель не был установлен в NULL. Как мне преодолеть это? Поскольку перегрузка деструктора не допускается.

Есть ли способ предотвратить эту ошибку времени выполнения? Это код :: http://ideone.com/SDkXY9 (Ideone не печатает вывод, я не знаю, почему!)

+0

ли следовать за вами [правило трех/пяти/ноль] (http://en.cppreference.com/w/cpp/language/rule_of_three)? Есть ли вероятность, что узел может быть удален дважды? Насколько глубоко дерево? –

+0

Да, узел удаляется дважды! Вот что я пытался объяснить в вопросе: «... во время вызова деструктора деструктор пытается удалить удаленный узел и этот указатель не был установлен в NULL ...» Основной вопрос что только так я могу справиться с этим? – user007

+0

Знаете ли вы, что узел удален ранее, или это вы просто угадываете? Может ли узел иметь несколько родителей? Вы (явно или неявно через сгенерированный компилятором экземпляр-конструктор или оператор копирования) копируете * указатель * на узел, а не на сам узел? –

ответ

2

Проблема здесь состоит в том, что вы пытаетесь удалить соседей, от которых инициируется прикован разрушение. Вам нужно будет добавить флаг, который вы можете проверить в деструкторе, для которого соседка нормальная, чтобы удалить.

~Node() { 
    _isDestructing = true; 
    if (!left->_isDestructing) delete left; 
    if (!right->_isDestructing) delete right; 
    left = NULL; 
    right = NULL; 
} 
Смежные вопросы