2013-12-13 3 views
3
template<class item_type> 
struct node{ 
    item_type x; 
    node<item_type> *left; 
    node<item_type> *right; 
    //functions 
}; 

template<class item_type, class param> 
class Tree{ 
     node<item_type> *root; 
    public: 
     item_type Get_Item(param item); 
     void Add_Item(item_type item); 
     void Delete_Item(item_type item); 

     //more functions 

     Tree(); 
}; 


template<class item_type, class param> 
Tree<item_type, param>::Tree() 
{ 
    this->root = new node<item_type>; 

    this->root->left=NULL; 
    this->root->right=NULL; 

} 

ADD ITEM:сбой программы при сравнении указателей на NULL

void Tree<item_type, param>::Add_Item(item_type item) 
{ 

    node<item_type> newItem; 
    newItem.x = item; 
    node<item_type> *cur = root; 
    node<item_type> *prev; 

    if(cur->x==NULL) 
     cur->x=item; 

    int ifGreater; 
    while(cur->left!=NULL || cur->right!=NULL) 
    { 
     if(item<cur->x) 
     { 
      ifGreater = 0; 
      prev = cur; 
      cur = cur->left; 
     } 
     else 
     { 
      ifGreater = 1; 
      prev = cur; 
      cur = cur->right; 
     } 
    } 
    if(ifGreater==1) 
     prev->right = &newItem; 
    if(ifGreater==0) 
     prev->left = &newItem; 
} 

Проблема возникает здесь, в этой функции в cout<<1;

template<class item_type, class param> 
    void Tree<item_type, param>::Delete_Item(item_type item) 
    { 
     node<item_type> *cur = root; 
     node<item_type> *prev; 

     int ifGreater; 
     if(cur==NULL) 
     { 
      cout<<"Not found"<<endl; 
      return; 
     } 

     while(cur!= NULL && (cur->left!=NULL || cur->right!=NULL)) 
     { 
      cout<<1; //crash occurs RIGHT before here as 1 is never printed 
      if(item<cur->x) 
      { 
       //do something 
      }        
     } 

Проблема возникает перед cout<<1 и после объявления int ifGreater;cout просто как раз, чтобы проверить, где он работает и где она перестает работать. я запустить эту функцию с помощью вызова

int main() 
{ 
    Tree<int,int> theTree; 
    theTree.Add_Item(1); //so the tree isn't empty 
    theTree.Delete_Item(1); 
} 

ПРИМЕЧАНИЯ: Программа даже не пройти первую итерацию, неправильное обращение с памятью (что фиксировано) не была проблемой этой конкретной ошибки.

+0

как вы инициализировали root? – pippin1289

+0

@ pippin1289 в конструкторе 'root = new node ' – SemicolonExpected

+3

По крайней мере, вы хотите вырваться из цикла после 'delete' текущего узла' cur'. Возможно, вам также понадобится исправить указатели, указывающие на этот узел, вероятно, до 'delete'ing. –

ответ

1

Вы неопределенное поведение в следующем фрагменте кода:

template <class item_type, class param> 
void Tree<item_type, param>::Add_Item(item_type item) 
{ 
    node<item_type> newItem; 
    // ... 
    if(ifGreater==1) 
     prev->right = &newItem; 
    if(ifGreater==0) 
     prev->left = &newItem;  
} 

Выше newItem является переменной местного и вы сохраняя указатель на что местное и после истечения срока его действия, когда Add_Item выходы. Вероятно, это является причиной аварии.

Кроме того, вы никогда не инициализировали ifGreater или node<item_type> *prev;. Опять же, это приводит к более неопределенному поведению, когда это запускается на выполнение:

if(ifGreater==1) 
     prev->right = &newItem; 
    if(ifGreater==0) 
     prev->left = &newItem;  

Вы, вероятно, в конечном итоге deferencing некоторые случайные кусок памяти. Это связано с тем, что нет никакой гарантии, что ваш цикл while выполняется, например. Рассмотрим случай, когда оба left и right составляют NULL.

+0

У меня был чек заранее, чтобы проверить if 'cur == NULL' или в случае' Add_Item() ', когда' cur-> x == NULL', так как всегда должен быть 'cur' . Я думал, что мне разрешено инициализировать указанные переменные в ветвях. – SemicolonExpected

+0

'cur-x' - полезная нагрузка, это данные, которые вы храните. Сравнение с «NULL» на самом деле неверно, если вы не сохраняете тип указателя. – greatwolf

+0

@SemicolonExpected Пока условие 'cur == NULL' является ложным, оно может указывать на недопустимое расположение памяти, хотя, поскольку вы однажды указали на временную переменную w/c, чтобы указатель зависал, когда эта временная переменная выходит из объем. См. [Dangling Pointer] (http://en.wikipedia.org/wiki/Dangling_pointer) – mr5

Смежные вопросы