Нарушение прав чтения при разрушении бинарного дерева поиска - PullRequest
0 голосов
/ 02 июня 2018

Добрый вечер.Я получаю ошибку исключения доступа при попытке уничтожить мой BST.Ранее были сообщения об этом, и я скопировал ответ на их принятый ответ, но так и не получил ожидаемого результата.Итак, у меня есть реализация бинарного дерева поиска.Все работает хорошо, пока мой код не достигнет «return 0» из моей функции int main ().

Я оставлю код для вас.

PQBST::~PQBST()
{
    destroy();
}

inline void PQBST::destroy()
{
    if (root)
        destroy(root);
}

void PQBST::destroy(Node* node)
{
    if (node->left) // this is where it gives me and access violation exception 0xDDDDDDDD
        destroy(node->left);
    if (node->right)
        destroy(node->right);
    delete node;
}

Я знаю, что такая ошибка возникает, когда вы пытаетесь удалить что-то, что уже было освобождено, но я не могу понять, почему он попытался бы дважды уничтожить мой BST, когда я вызываюуничтожить функцию только один раз в моем приложении (когда я закончу с этим).Я прокомментировал часть, где я вручную уничтожаю свой BST, и после достижения «return 0» он снова дает мне

Unhandled exception thrown: read access violation.
node was 0xFF12C6AB

, так что это не 0xDDDDDDDD, но все равно ошибка.: |

Мои узлы выглядят так:

struct Node
{
    Human info;
    Node * left;
    Node * right;
    Node() {};
    Node(Human value)
        : info(value), left(NULL), right(NULL)
    {

    }
};

Мой класс BST имеет только Node * root.Я надеюсь, что дал вам достаточно информации.Спасибо.

Редактировать: Теперь мои узлы выглядят так:

    struct Node
{
    Human info;
    Node * left;
    Node * right;
    Node() { left = NULL, right = NULL;  }
    Node(Human value): info(value), left(NULL), right(NULL){}
    Node(Human value, Node* left, Node* right) : info(value), left(left), right(right) {}
    Node& operator=(const Node& n)
    {
        info = n.info;
        left = n.left;
        right = n.right;

        return *this;
    }

    Human getInfo() const { return info; }
    Node* getLeft() { return left; }
    Node* getRight() { return right;  }
    ~Node() { };
};

Мой PQBST:

class PQBST
{
private:
    Node * root;
    int m; //spaceship size - given by the user

public:
    PQBST() { root = NULL; }
    PQBST(int m) : root(NULL), m(m) {}
    PQBST(Node* root, int m);
    ~PQBST();

PQBST::PQBST(Node * root, int m)
{
    this->root = root;
    this->m = m;
}

Ответы [ 2 ]

0 голосов
/ 02 июня 2018

Я знаю, что ошибка такого рода возникает, когда вы пытаетесь удалить что-то, что уже было освобождено, но я не могу понять, почему он попытается уничтожить мой BST дважды , когда я вызываюуничтожить функцию только один раз в моем приложении (когда я закончу с этим) .

Не уверен, правильно ли я понимаю то, что вы сказали выше (жирным шрифтом), но разве вы не звоните PQBST::destroy() уже в PQBST::~PQBST()?Если вы вызываете PQBST::destroy() также вручную, будет ли он вызываться дважды при вызове деструктора?

0 голосов
/ 02 июня 2018

Если вы собираетесь удалить свой BST, я предлагаю сделать обход после заказа .Это будет посещать левый, правый рекурсивно, а затем удалить узел.Это сработало бы, если бы дерево было построено правильно.

void PQBST::destroy(Node* node)
{
    if (!node) return;
    destroy(node->left);
    destroy(node->right);
    delete node;
}

Сказав это, я бы предложил отойти от попыток вручную управлять памятью и использовать std::unique_ptr<T>, где T - тип вашего узла.Я бы определил их в вашем BST как std::unique_ptr<Node> left, right;.Это позволяет полностью избежать этой проблемы.

...