2013-12-13 203 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