为什么在while循环中指针的值会改变?

时间:2019-05-13 18:53:17

标签: c++

我有以下代码:

    #include <iostream>
#include <cstring>
using namespace std;
class lexicon{
 private:
   class node{
       public:
    string s = "";
    int freq;
    node *left=nullptr;
    node *right=nullptr;
    friend class lexicon;
   };
   node *root;

 public:
void display(node *pd)const{
    if(pd==nullptr)return;
    display(pd->left);
    cout << root->s << " " << root->freq << endl;
    display(pd->right);
   }
   lexicon(){
    root=nullptr;
   }
   ~lexicon(){
    delete root;
   }
   void insert(const string &s1){
    if(root==nullptr){
     root= new node;
     root->s=s1;
     root->freq=1;
     root->left=root->right=nullptr;
    }else{
     node *point=root;
     string s6 = point->s;
     if(point->s!=s1)cout << "1";
     node *pppp=point;
     while(s1!=(point->s) && point!=nullptr){   //this is where the problem occurs
      if(s1>(point->s))point=point->right;
      else if(s1<(point->s))point=point->left;
     }
     if(point==nullptr){
      point = new node;
      point->s=s1;
      point->freq = 1;
      point->left=point->right=nullptr;
     }else{
      ++(point->freq);
     }
    }
   }
   int lookup(const string &s)const{
    node *point=root;
    if(point==nullptr)return 0;
    while(point->s!=s && point!=nullptr){
   if(s>point->s)point=point->right;
     else if(s<point->s)point=point->left;
    }
    if(point==nullptr)return 0;
    else return point->freq;
   }
   int depth(const string &s)const{
   int count = 1;
    node *point=root;
    if(point==nullptr)return 0;
    while(point->s!=s && point!=nullptr){
     if(s>point->s)point=point->right;
     else if(s<point->s)point=point->left;
     ++count;
    }
    if(point==nullptr)return 0;
    else return count;
   }
   void replace(const string &s1, const string &s2){
    int side;
    node *point1=nullptr;
    node *point=root;
    if(point==nullptr)return;
    while(point->s!=s1 && point!=nullptr){
     point1=point;
     if(s1>point->s){point=point->right; side=1;}
     else if(s1<point->s){side=-1; point=point->left;}
    }
    if(point==nullptr)return;
    int k=point->freq;
    if(point->right==nullptr && point->left!=nullptr){
     if(side==1)point1->right=point->left;
     if(side==-1)point1->left=point->left;
     point->left=nullptr;
     delete point;
    }else if(point->left==nullptr && point->right!=nullptr){
     if(side==1)point1->right=point->right;
     if(side==-1)point1->left=point->right;
     point->right=nullptr;
     delete point;
    }else if(point->left==nullptr && point->right==nullptr){
     if(side==1)point1->right=nullptr;
     if(side==-1)point1->left=nullptr;
     delete point;
    }else{
     node *small = point->left;
     if(small->right==nullptr){
      small->right=point->right;
      if(side==1)point1->right=small;
      if(side==-1)point1->left=small;
      point->right=point->left=nullptr;
      delete point;
     }else{
     node *smallb, *small=point->left;
     while(point->right!=nullptr){
      smallb=small;
      small=small->right;
     }
     smallb->right=small->left;
     if(side==1)point1->right=small;
     if(side==-1)point1->left=small;
     small->right=point->right;
     small->left=point->left;
     point->left=point->right=nullptr;
     delete point;
     }
    }
    node *start=root, *startb;
    int ns=0;
    while(start->s!=s2 && start!=nullptr){
     startb=start;
     if(s2>start->s){ns=1; start=start->right;}
     if(s2<start->s){start=start->left; ns=-1;}
    }
    if(start==nullptr){
     if(ns==1){
      startb->right=new node;
      (startb->right)->s=s2;
      (startb->right)->freq=k;
     }if(ns==-1){
      startb->left=new node;
      (startb->left)->s=s2;
      (startb->left)->freq=k;
     }
    }else{
     start->freq+=k;
    }
   }
   friend ostream & operator<<(ostream &out, const lexicon &l){
    l.display(l.root);
    return out;
   }
};
int main(){
  cout <<"1";
 lexicon l;
 l.insert("the");
 l.insert("boy");
 l.insert("and");
 l.insert("the");
 l.insert("wolf");
 cout << "the word 'the' is found " << l.lookup("the") << " tine(s)" << endl;
 cout << "the word 'and' is found at depth " << l.depth("and") << endl;
 cout << l;
 l.replace("boy", "wolf");
 cout << "Aftr replacement:" << endl;
 cout << l;
 cout << "Now the word 'and' is found at depth: "<<l.depth("and")<<endl;
 return 0;
}

当我通过调试器运行它时,它停在我有注释的行,并出现分段错误错误。如您所见,我将点设置为等于根,然后将pppp设置为等于点。调试器显示root的值为0x615c50,但该点的值为0x0。最奇怪的是pppp的正确值为0x615c50。我不知道为什么我调用while循环时将point的值设置为0x0。我使用的调试器是onlinegdb。我所附的图片在右侧显示了变量的值,紧随其后的是在此行显示了分段错误。感谢您的任何提前帮助。

enter image description here enter image description here

2 个答案:

答案 0 :(得分:1)

  

为什么while循环中指针的值会改变?

 while(s1!=(point->s) && point!=nullptr){   //this is where the problem occurs
  if(s1>(point->s))point=point->right;
  else if(s1<(point->s))point=point->left;
 }

您正在point块的两个分支中更改if的值。当然point会在循环中发生变化。

代码中的问题是,即使将point->s设置为point,您仍在引用nullptr中的指针。

您需要将while语句的条件更改为:

 while ( point != nullptr && s1 != (point->s) { ... }

答案 1 :(得分:1)

您的情况是错误的解决方法:

while(s1!=(point->s) && point!=nullptr)

在取消引用之前,应先检查point是否有效。即将其更改为

while(point!=nullptr && s1!=(point->s))

虽然您的代码中可能还有更多问题。