Member 13500537 Ответов: 3

Как мне избавиться от своей ошибки сегментации


#include "binTree.h"
#include <algorithm>
#include <iostream>
#include <iomanip>

using namespace std;

#ifndef BINSTREE_H
#define BINSTREE_H

template <class T>
class binSTree : public binTree <t>
{
public:
binSTree( Node <t> *r = NULL ): binTree<t>::binTree(r) {}
void insert(const T& x){ insert(root, x); }
void remove(const T& x){ remove(root, x); }
unsigned size() const{ return size(root); }
protected:
Node <t> * root;
private:
void insert(Node <t>*&, const T& );
void remove(Node <t> *&, const T&);
unsigned size( Node<t>* node) const{
int l;
int ll;
int lr;
if(!node){ l = 0; }
else if(!node->left && !node->right){ l = 1; }
else{
ll = size(node->left);
lr = size(node->right);
l=ll+lr;
}
return l; }
Node <t>* pred( Node<t>*& node){
node = node->left;
while(node != NULL){ node = node->right; }
return node;}

};

template <class T>
void binSTree<t>::insert(Node <t>*& node, const T& x)
{
if(!node){ node = new Node<t>(x); }
else if( x < node->data ){ insert(node->left, x); }
else if( x > node->data ){ insert(node->right, x); }
}

template <class T>
void binSTree<t>::remove(Node <t> *& node, const T& x)
{
if(x < node->data){ remove(node->left, x); }
else if(x > node->data){ remove(node->right, x); }
else if(x == node->data)
{
if(node->left == NULL && node->right == NULL){ delete node; }
else if( node->left != NULL )
{
Node<t>* temp = pred(node);
temp->left = node->left;
delete node;
}
else if(node->right != NULL )
{
Node<t>* temp = pred(node);
temp->right = node->right;
delete node;
}
else
{
Node<t>* temp = pred(node);
node = node->left;
while(node->right != NULL){ node = node->right; }
node = temp;
Node<t>* temp2 = pred(node);
delete temp;
temp2->left = node;
}
}
}
#endif

What I have tried:

I'm sure the problem is here somewhere, I've mostly been eliminating loops trying to find the problem

not sure where to start

it's a seg fault core dump

Peter_in_2780

Одно слово. ОТЛАДЧИК

Member 13500537

Отладчик только что сказал мне, что он падает в if(x < node->data), и это утверждение должно быть правильным?

в функции insert первая итерация

nv3

Ну а если отладчик винит оператор "if (x < node->data)", то посмотрите на значение node. Я предполагаю, что он равен 0 или не определен, что в свою очередь приводит к ошибке сегментации. Следующий шаг-выяснить, почему узел имеет неправильное значение в данной конкретной тестовой ситуации. Вот как работает отладка.

3 Ответов

Рейтинг:
1

Patrice T

Цитата:
Как мне избавиться от своей ошибки сегментации

Ваш код не является автономным, мы не можем воспроизвести проблему, просто угадайте.
Используйте отладчик для проверки переменных и убедитесь, что любой пустой указатель равен нулю, как и ожидалось.
-----
Научитесь правильно делать отступы в вашем коде, это покажет его структуру, и это поможет чтению и пониманию.
#include "binTree.h"
#include <algorithm>
#include <iostream>
#include <iomanip>

using namespace std;

#ifndef BINSTREE_H
#define BINSTREE_H

template <class T>
class binSTree : public binTree <t>
  {
    public:
      binSTree( Node <t> *r = NULL ): binTree<t>::binTree(r) {}
      void insert(const T& x){ insert(root, x); }
      void remove(const T& x){ remove(root, x); }
      unsigned size() const{ return size(root); }
    protected:
      Node <t> * root;
    private:
      void insert(Node <t>*&, const T& );
      void remove(Node <t> *&, const T&);
      unsigned size( Node<t>* node) const{
        int l;
        int ll;
        int lr;
        if(!node)
        {
          l = 0;
        }
        else if(!node->left && !node->right)
        {
          l = 1;
        }
        else{
          ll = size(node->left);
          lr = size(node->right);
          l=ll+lr;
        }
        return l;
      }
      Node <t>* pred( Node<t>*& node){
        node = node->left;
        while(node != NULL)
        {
          node = node->right;
        }
      return node;}

    };

    template <class T>
    void binSTree<t>::insert(Node <t>*& node, const T& x)
      {
        if(!node)
        {
          node = new Node<t>(x);
        }
        else if( x < node->data )
        {
          insert(node->left, x);
        }
        else if( x > node->data )
        {
          insert(node->right, x);
        }
      }

    template <class T>
    void binSTree<t>::remove(Node <t> *& node, const T& x)
      {
        if(x < node->data)
        {
          remove(node->left, x);
        }
        else if(x > node->data)
        {
          remove(node->right, x);
        }
        else if(x == node->data)
        {
          if(node->left == NULL && node->right == NULL)
          {
            delete node;
          }
          else if( node->left != NULL )
          {
            Node<t>* temp = pred(node);
            temp->left = node->left;
            delete node;
          }
          else if(node->right != NULL )
          {
            Node<t>* temp = pred(node);
            temp->right = node->right;
            delete node;
          }
          else
          {
            Node<t>* temp = pred(node);
            node = node->left;
            while(node->right != NULL)
            {
              node = node->right;
            }
            node = temp;
            Node<t>* temp2 = pred(node);
            delete temp;
            temp2->left = node;
          }
        }
      }
      #endif

Профессиональные редакторы программистов имеют эту функцию и другие, такие как сопоставление скобок и подсветка синтаксиса.
Блокнот++ Главная Страница[^]
личные[^]


Рейтинг:
1

CPallini

Цитата:
Отладчик только что сказал мне, что он падает в if(x < node->data), и это утверждение должно быть правильным?

потому что вы не провели проверку на вменяемость:
if ( ! node )
{
  // handle error
}
или
assert(node);

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


Рейтинг:
0

Jochen Arndt

Ваш root член не инициализируется.
Я думаю, что он должен быть установлен на значение, переданное в конструкторе:

binSTree( Node <t> *r = NULL ): binTree<t>::binTree(r), root(r) {}

Вы также должны установить пройденное Node указатель на NULL после удаления его в remove() функция:
// ...
Node<t>* temp = pred(node);
temp->left = node->left;
delete node;
// Insert this line after each delete
node = NULL;
// ...

Ваш pred() функция возвращает всегда NULL:
Node <t>* pred( Node<t>*& node)
{
    // Missing check for NULL here
    node = node->left;
    while(node != NULL)
        node = node->right; 
    // node is always NULL here!
    return node;
}
Эта функция также изменяет содержимое, потому что node передается по ссылке. Было бы лучше пройти а const вместо этого наведите указатель и сделайте функцию const тоже.

Наконец, вы должны - как уже предлагалось - всегда проверять, прошел ли он Node указатели есть NULL Но эти проверки завершатся неудачей (укажут на успех) для ненулевых, но недопустимых указателей (не инициализированных и не удаленных между тем).