2013-12-13 201 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; 

} 

添加項:程序崩潰

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

至少你希望在刪除當前節點'cur'後退出循環。你可能還需要修補指向這個節點的指針,可能在刪除它之前。 –

回答

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退出之後。這可能是墜機的原因。

此外,您從未初始化ifGreaternode<item_type> *prev;。再次,這將導致更多的不確定的行爲時,這得到執行:

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

你有可能最終deferencing一些隨機的內存塊。這是因爲不能保證您的while循環執行,例如。考慮leftright都是NULL的情況。

+0

我有一個事先檢查,以檢查是否'CUR == NULL'或'方法add_item()'的情況下,當'CUR-> X == NULL'因爲應該永遠是一個'cur' 還我以爲我被允許在分支中初始化上述變量。 – SemicolonExpected

+0

'cur-x'是有效載荷,它是你正在存儲的數據。除非你存儲指針類型,否則將它與NULL比較是不正確的。 – greatwolf

+0

@SemicolonExpected雖然CUR的'條件== NULL'是假的,它可能指向一個無效的內存位置,但因爲你曾經將它指向一個臨時變量W/C會使指針時臨時變量超出垂下來範圍。參見[懸掛指針(http://en.wikipedia.org/wiki/Dangling_pointer) – mr5