Dangling Pointer - пожалуйста, подтвердите

0

Может ли кто-нибудь проверить и сказать мне, действует ли следующий код? Я чувствую, что линии 160-162 могут быть неправильными.
У меня есть комментарии, чтобы указать номер строки.
полный код берется здесь C++ Дерево двоичного поиска

class BinarySearchTree
{
    private:
        struct tree_node
        {
           tree_node* left;
           tree_node* right;
           int data;
        };
        tree_node* root;

    public:
        BinarySearchTree()
        {
           root = NULL;
        }

        bool isEmpty() const { return root==NULL; }
        void print_inorder();
        void inorder(tree_node*);
        void print_preorder();
        void preorder(tree_node*);
        void print_postorder();
        void postorder(tree_node*);
        void insert(int);
        void remove(int);
};


void BinarySearchTree::remove(int d)
{
    //Locate the element
    bool found = false;
    if(isEmpty())
    {
        cout<<" This Tree is empty! "<<endl;
        return;
    }

    tree_node* curr;
    tree_node* parent;
    curr = root;

    while(curr != NULL)
    {
         if(curr->data == d)
         {
            found = true;
            break;
         }
         else
         {
             parent = curr;
             if(d>curr->data) curr = curr->right;
             else curr = curr->left;
         }
    }
    if(!found)
         {
        cout<<" Data not found! "<<endl;
        return;
    }


         // 3 cases :
    // 1. We're removing a leaf node
    // 2. We're removing a node with a single child
    // 3. we're removing a node with 2 children

    // Node with single child
    if((curr->left == NULL && curr->right != NULL)|| (curr->left != NULL
&& curr->right == NULL))
    {
       if(curr->left == NULL && curr->right != NULL)
       {
           if(parent->left == curr)
           {
             parent->left = curr->right;
             delete curr;
           }
           else
           {
             parent->right = curr->right;
             delete curr;
           }
       }
       else // left child present, no right child
       {
          if(parent->left == curr)
           {
             parent->left = curr->left;
             delete curr;
           }
           else
           {
             parent->right = curr->left;
             delete curr;
           }
       }
     return;
    }

         //We're looking at a leaf node
         if( curr->left == NULL && curr->right == NULL)
    {
        if(parent->left == curr) parent->left = NULL;
        else parent->right = NULL;
                 delete curr;
                 return;
    }


    //Node with 2 children
    // replace node with smallest value in right subtree
    if (curr->left != NULL && curr->right != NULL)
    {
        tree_node* chkr;
        chkr = curr->right;
        if((chkr->left == NULL) && (chkr->right == NULL))
        {
            curr = chkr;  // <----------- line 160
            delete chkr;
            curr->right = NULL; // <------------------ line 162
        }
        else // right child has children
        {
            //if the node right child has a left child
            // Move all the way down left to locate smallest element

            if((curr->right)->left != NULL)
            {
                tree_node* lcurr;
                tree_node* lcurrp;
                lcurrp = curr->right;
                lcurr = (curr->right)->left;
                while(lcurr->left != NULL)
                {
                   lcurrp = lcurr;
                   lcurr = lcurr->left;
                }
        curr->data = lcurr->data;
                delete lcurr;
                lcurrp->left = NULL;
           }
           else
           {
               tree_node* tmp;
               tmp = curr->right;
               curr->data = tmp->data;
           curr->right = tmp->right;
               delete tmp;
           }

        }
         return;
    }

}

curr и chkr указывают на то же место. Удалив chkr, может ли доступ к тому же местоположению по-разному? Или это хорошо, потому что ни один из них на самом деле не выделял какую-либо память, используя новый оператор.

В коде есть что-то действительно изворотливое. Я чувствую, что есть утечка памяти. Я работаю профессионалом, желающим освежить мои основы C++. Спасибо за любую помощь.

  • 0
    Я бы скопировал ту часть кода, о которой вы говорите, вместе с определением класса.
  • 0
    «Действительно хитроумно» правильно - у этого кода есть все виды проблем. Вы можете обновить свои знания в другом месте :-)
Показать ещё 1 комментарий
Теги:
memory-leaks
binary-search-tree
dangling-pointer

2 ответа

1
Лучший ответ

Я взглянул на код вокруг региона, о котором вы говорили. Я считаю, что вы правы, так как это ошибка.

void BinarySearchTree::remove(int d)
{

...

    tree_node* curr;
    tree_node* parent;
    curr = root;

...    

    //Node with 2 children
    // replace node with smallest value in right subtree
    if (curr->left != NULL && curr->right != NULL)
    {
        tree_node* chkr;
        chkr = curr->right;
        if((chkr->left == NULL) && (chkr->right == NULL))
        {
            curr = chkr;
            delete chkr;
            curr->right = NULL;
        }

В этом разделе кода, curr и chkr объявляются как указатель на экземпляр tree_node. При запуске curr = chkr значение указателя для chkr wirtten to curr и, следовательно, указывает на то, к чему указывает chkr. delete chkr, экземпляр уничтожается и сбор мусора. Таким образом, curr теперь указывает на несуществующий объект, который не в жизни. Это, по-видимому, повисший указатель, если я правильно помню.

Если я все правильно понял и понял этот конкретный фрагмент, следующим является исправление:

curr->data = chkr->data;

заменить

       curr = chkr;

Что касается утечки памяти. Извините, я не прочитал весь код. Кажется, что msram-код должен быть просто для отображения правильной логики. Это намного больше дополнительной информации для этой цели.

0

Да, строки 160-162 содержат ошибку, как вы описали. Он пишет в память, что он выпустил с delete.

Ещё вопросы

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