C++:二叉搜索树分段错误

C++:二叉搜索树分段错误,c++,recursion,tree,segmentation-fault,binary-search-tree,C++,Recursion,Tree,Segmentation Fault,Binary Search Tree,我正在制作一个二进制搜索树,它用包含字符串代码和整数的对象填充树,这些对象是从文本文件中读取的。另一个函数通过读取另一个文本文件、搜索该对象、更新其数量来更新树,如果数量达到0,则删除节点 我的程序工作到Update.txt文件中需要搜索和更新的第8个对象。在我的调试器中,我在BSTree.template的第113行收到一个segfault,其内容为:else if q_ptr->data==obj。这相当令人困惑,因为前面的if语句询问q_ptr是否为NULL。如果它移动到else,这只能意

我正在制作一个二进制搜索树,它用包含字符串代码和整数的对象填充树,这些对象是从文本文件中读取的。另一个函数通过读取另一个文本文件、搜索该对象、更新其数量来更新树,如果数量达到0,则删除节点

我的程序工作到Update.txt文件中需要搜索和更新的第8个对象。在我的调试器中,我在BSTree.template的第113行收到一个segfault,其内容为:else if q_ptr->data==obj。这相当令人困惑,因为前面的if语句询问q_ptr是否为NULL。如果它移动到else,这只能意味着它包含数据

以下是DBInterface.cpp中的“从文件更新”函数:

下面是BSTree.template中的BSTree::remove函数


仅仅因为指针不是NULL,所以使用nullptr btw并不意味着它是有效的。获取“nullptr”是c++11[-Wc++0x-compat]中的一个关键字。我几个月前才在这台电脑上设置了这些,所以我怀疑我是否有过时的编译器?nullptr只是NULL的更好替代品。我怀疑这是你问题的根源。最有可能的情况是,您正在传递悬空指针。Hmmm,我告诉调试器在BSTree::update中显示ptr->data和itm。它告诉我数量=2685724,代码=\\sX。在这个特殊的项目上,itm的数量=14,代码=AM0755,这就是它正在搜索的。我觉得奇怪的是,在函数的递归过程中,当调试器告诉我不同时,它传递了if语句ptr->data==itm?在分配新节点时,可能没有清空右/左指针。
    void DBInterface::updateFromFile(string f_Name) 
{
    ifstream file (f_Name.c_str());
    string line;


    if (file.is_open())
    {
        std::getline(file, line);
        while (std::getline (file, line))
        {
            std::istringstream iss (line);
            int q=0;
            int pos=0;
            pos = line.find('\t',0); //find position of blank space
            string tmp_str = line.substr(0,pos); //create a substring
            string tmp_str1 = line.substr((pos+1), string::npos);
            stringstream ss (tmp_str1);
            ss >> q;
            MechPart tmp_mp;
            MechPart currentQuantity;
            tmp_mp.set_code(tmp_str); //set code
            tmp_mp.set_quantity(q);
            cout << "Current data: " << tmp_mp.get_code() << " | " << tmp_mp.get_quantity() << endl;
            currentQuantity = tree.quantitySearch(tree.getRoot(), tmp_mp);
            int new_quantity = currentQuantity.get_quantity();
            tmp_mp.set_quantity(new_quantity + q);

            BTNode<MechPart>* updated_ptr = tree.update(tree.getRoot(), tmp_mp);
            if (updated_ptr->data() <= 0)
            {
                tree.remove(updated_ptr);
            }


        }
    }
    file.close();
    template <typename Item>
Item BSTree<Item>::quantitySearch(BTNode<Item>* q_ptr, Item obj)
{
    if (q_ptr == NULL)
    {
        //POINTER IS NULL
        return obj;
    }
    else if (q_ptr->data() == obj)
    {
        return q_ptr->data();
    }

    else if (obj > q_ptr->data()) 
    { //WORK ON RIGHT SIDE
        return quantitySearch(q_ptr->get_right(), obj);
    }
    else
    {
    //work on left side
        return quantitySearch(q_ptr->get_left(), obj);

    }

}
template <typename Item>
void BSTree<Item>::remove(BTNode<Item>* rptr)
{
 //Locate the element
bool found = false;
if(root==NULL)
{
    //cout<<" This Tree is empty "<<endl;
    return;
}

BTNode<Item>* curr;
BTNode<Item>* parent;
curr = root;

while(curr != NULL)
{
     if(curr->data() == rptr->data())
     {
        found = true;
        break;
     }
     else
     {
         parent = curr;
         if(rptr->data() > curr->data())
         {
            curr = curr->get_right(); //if Item's data is greater than curr's data, point to the parent's right child
         }
         else 
         {
            curr = curr->get_left(); //else point to left branch
         }
     }
}
if(!found)
     {
    //cout<<" Data not found! "<<endl;
    return;
}


// Node with single child
if((curr->get_left() == NULL && curr->get_right() != NULL)|| (curr->get_left() != NULL
&& curr->get_right() == NULL))
{
   if(curr->get_left() == NULL && curr->get_right() != NULL) 
//IF the right child is not null, left child NULL
       {
           if(parent->get_left() == curr)
           {
            parent->set_left(curr->get_right());
            delete curr;
           }
           else
           {
            parent->set_right(curr->get_right());
            delete curr;
           }
       }
       else 
//  1 -- 0 Left child present, right child NULL
       {
          if(parent->get_left() == curr)
           {
             parent->set_left(curr->get_left());
             delete curr;
           }
           else
           {
             parent->set_right(curr->get_left());
             delete curr;
           }
       }
     return;
    }

//leaf node
         if( curr->get_left() == NULL && curr->get_right() == NULL)
    {
        if(parent->get_left() == curr)
        {
            parent->set_left(NULL);
        }
        else parent->set_right(NULL);
        delete curr;
        return;
    }


//Node with 2 children
// replace node with smallest value in right subtree
    if (curr->get_left() != NULL && curr->get_right() != NULL)
    {
        BTNode<Item>* chkr;
        chkr = curr->get_right();
        if((chkr->get_left() == NULL) && (chkr->get_right() == NULL))
        {
            curr = chkr;
            delete chkr;
            curr->set_right(NULL);
        }
        else // right child has children
        {
            //if the node's right child has a left child
            // Move all the way down left to locate smallest element

            if((curr->get_right())->get_left() != NULL)
            {
                BTNode<Item>* lcurr;
                BTNode<Item>* lcurrp;
                lcurrp = curr->get_right();
                lcurr = (curr->get_right())->get_left();
                while(lcurr->get_left() != NULL)
                {
                   lcurrp = lcurr;
                   lcurr = lcurr->get_left();
                }
        curr->set_data(lcurr->data());
                delete lcurr;
                lcurrp->set_left(NULL);
           }
           else
           {
                BTNode<Item>* tmp;
                tmp = curr->get_right();
                curr->set_data(tmp->data());
                curr->set_right(tmp->get_right());
                delete tmp;
           }

        }
         return;
    }

}
    template <typename Item>
BTNode<Item>* BSTree<Item>::update(BTNode<Item>* ptr, Item itm)
{
    if (ptr == NULL)
    {
        //POINTER IS NULL
    }
    else if (ptr->data() == itm)
    {
        ptr->set_data(itm);

    }

    else if (itm > ptr->data()) 
    { //WORK ON RIGHT SIDE
        return update(ptr->get_right(), itm);
    }
    else
    {
    //work on left side
        return update(ptr->get_left(), itm);

    }
    return ptr;

}
    template <typename Item>
void BSTree<Item>::insert(BTNode<Item>* node, Item it) {


    if (root == NULL)
    {
    root = new BTNode<Item>(it);
    }
    else if (node == NULL)
    {
        node = new BTNode<Item>(it);
    }
    else if (it > node->data()) 
    {
        if (node->get_right() == NULL) 
        {
            BTNode<Item>* tmp = node->get_right();
            tmp = new BTNode<Item>(it);
            node->set_right(tmp);

        }
        else 
        {
            insert(node->get_right(), it);
        }
    }
    else if (node->get_left() == NULL) 
    {
        //work on left side
            BTNode<Item>* tmp = node->get_left();
            tmp = new BTNode<Item>(it);
            node->set_left(tmp);

    }
    else 
    {
        insert (node->get_left(), it);
    }

}
    void DBInterface::readFromFile(string fName) {
    ifstream file (fName.c_str());

    string line;

    MechPart mechP;
    if (file.is_open())
    {
        std::getline (file, line);
        while (std::getline (file, line))
        {
            //bool test= tree.getEmpty();
            std::istringstream iss (line);
            int i=0;


            int stop;
            stop = line.find('\t',0); //find position of blank space
            string tmp_str = line.substr(0,stop); //create a substring
            string tmp_str1 = line.substr((stop+1), string::npos);
            stringstream ss (tmp_str1);
            ss >> i;
            mechP.set_quantity(i); //set quantity

            mechP.set_code(tmp_str); //set code
            tree.insertRoot(mechP); //insert into the tree
            cout << "Current line: " << tmp_str << " Current quantity: " << i << endl;
        }

    }
    file.close();
}
    template <typename Object>
BTNode<Object>::BTNode() { //default constructor
    left= NULL;
    right= NULL;
    parent= NULL;



}
template <typename Object>
BTNode<Object>::BTNode(Object initial_val) { //constructor with parameters
    item = initial_val;
    left = NULL;
    right = NULL;
    parent = NULL;
}