C ++ - GDB Вопрос об ошибке

голоса
1

Я работаю на бинарном дереве поиска в C ++. Я получаю следующие ошибки сообщенные после запуска GDB (я получать Segfault) на моей программе:

#0  0x08049058 in searchTree::tree_node<int>::getLeft (this=0x0) at bst.hxx:75
#1  0x08048ed8 in searchTree::bst_iter<int>::operator++ (this=0xbffff4b4) at bst.hxx:586
#2  0x08048a72 in main () at projectmain.cxx:29

# 0 Ошибка относится к моей функции getLeft (), которая выглядит следующим образом:

    template <typename T>
    inline tree_node<T>* tree_node<T>::getLeft() const
    {
        return tree_node<T>::left_; //note that left_ is of type tree_node<T>*
    }

Ошибка # 1 относится к моему оператору ++, определенному в моих итераторах, которая выглядит следующим образом:

        bst_iter<T>& operator++()
        { //note that s is a stack of tree_node<T>*
            tree_node<T> *p = pos_->getRight();
            s.push(p);
            for(p=p->getLeft(); p!=NULL; p=p->getLeft())
            {
                s.push(p);
            }
            pos_ = s.top();
            s.pop();
            return *this;
        }

Ошибка # 2 относится к моей основной программе, в которой я включаю файл, который содержит мои определения для tree_node, BinaryTree, bst_iter и bst_citer (который не существует на данный момент, так что не проблема).

                            bst_iter<int> i = treeTime.begin(); //treeTime is our tree
            bst_iter<int> iEnd = treeTime.end();
                            for(; i != iEnd ;++i) //crash
            {
                cout<<*i<< ;
            }

        template <typename T>
        inline bst_iter<T> binaryTree<T>::begin()
         {

             return bst_iter<T>(root_);
         }

        template <typename T>
        inline bst_iter<T> binaryTree<T>::end()
         {
            return bst_iter<T>(0);
         }

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

Задан 05/04/2011 в 02:32
источник пользователем
На других языках...                            


3 ответов

голоса
1

Как вы Инициализация итератора контура I? Если это недопустимое, чтобы начать с, то это было бы объяснить.

Ответил 05/04/2011 в 02:36
источник пользователем

голоса
0

Это может произойти, если позиция _-> GetRight () возвращает нулевой указатель.

Так как вы вызываете getLeft на результат, не проверяя его на нуль, вы в конечном итоге с этим указателем, который является нулевым.

Ответил 05/04/2011 в 02:46
источник пользователем

голоса
0

Как вы можете видеть в GdB обратной трассировке, вы в конечном итоге вызова getLeft()на указатель NULL. т.е. его этот указатель NULL.

В вашем цикле внутри operator++, вы звоните getLeft()на pбез предварительной проверки , если это NULL. то есть , если getRight()возвращается NULL, вы будете врезаться.

Вы, вероятно, хотите сделать что-то вроде этого:

bst_iter<T>& operator++()
    { //note that s is a stack of tree_node<T>*
        tree_node<T> *p = pos_->getRight();
        if (p == NULL) p = pos_;
        else s.push(p);
        for(p=p->getLeft(); p!=NULL; p=p->getLeft())
        {
            s.push(p);
        }
        // TODO: what if s is empty?
        pos_ = s.top();
        s.pop();
        return *this;
    }

Это не полный фикс , хотя. Это зависит немного о том , что ваше end()состояние итератора должно быть.

Тем не менее, кажется , что есть более эффективные и более интуитивные способы реализации operator++. STL, например , позволяет удалять записи в дереве и только основание недействительности итераторы , указывающие на этот узел. В вашем случае, все итераторы должны быть признаны недействительными.

Ответил 05/04/2011 в 02:46
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more