CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Nov 2009
    Posts
    3

    Annoying linked list error

    I'm trying to write code that takes can read in ordered triples from a file, store them in a linked list and spit them out again, but I get a strange error.

    If I manually code in the triples (1,1,1) (2,2,2) and (4,4,4), and try to display them, I get (1,1,1)(4,4,4)(4,4,4)(4,4,4)(4,4,4) etc.

    If I try to read the ordered triples in from a file, I also get a strange problem where the first triple is correct, but only one other, incorrect triple appears.

    When I run the debugger, it displays "Segmentation Fault" when I get to the line in "displayTripleList" that is commented as "supererror"

    I basically took a linked list that was on my computer and tried to modify it, so there are some vestigial pieces of code, such as anything related to polynomials.

    Here's the code
    Code:
    #include <math.h>
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    class orderedTriple{
          private: double xcoord, ycoord, strength;
          public: 
                  orderedTriple(){xcoord=ycoord=strength=0;}
                  orderedTriple(double x, double y, double z){
                                       xcoord=x; ycoord=y; strength=z;}
                  orderedTriple getForce(double x, double y){
                                double a,b,c;
                                a=x-xcoord; b=y-ycoord; c=strength/sqrt(pow(a,2)+pow(b,2));
                                orderedTriple force(a,b,c);
                                return force;
                                };
                  void setx(double x){xcoord=x;}
                  void sety(double x){ycoord=x;}
                  void setz(double x){strength=x;}
                  double returnx(){return xcoord;}
                  double returny(){return ycoord;}
                  double returnz(){return strength;}
                  };
    void display(orderedTriple Lynn){
         cout<<"("<<Lynn.returnx()<<","<<Lynn.returny()<<","<<Lynn.returnz()<<")";
         }             
                  
     class string {
          private: int n; char letters[25];
          public:
                 string(){n=0; for (int i=0; i<25; i++) letters[i]='0';}
                 string(int k, char p[]) {n=k; for (int i=0; i<k; i++) letters[i]=p[i];}
                 void display(){for (int i=0; i<n; i++) cout<<letters[i];}
                 void appendLetter (char Rachel) {n++; letters[n-1]=Rachel;}
                 };//this class probably isn't necessary.
                 
                 
    
    
    struct node{
           orderedTriple dunce;
           double coff;
           double exp;
           char p;
           node* next;
           };
    
    
    //Here's the linkedList class
    class linkedList{
    
    private:
          node head;
          node* current;
          int length;
    
    public:
          linkedList();
          void addNode(node toAdd);
          double evaluate(double a);
          int returnLength();
          node returnCurrent();
          void transverse();
          linkedList convertToNumbers(linkedList poly);
          char returnCharacter();
          void incrementExponents();//useful for creating multi-digit numbers.
          void integrate();
          void setCurrent(node* a);
          void deleteList();
          void displayCharacterList();
          void displayTripleList();
          orderedTriple sumForces(orderedTriple test);
          orderedTriple rungeKutta(orderedTriple test);
          };
    
    //Function declarations
    node makeNode(orderedTriple);
    node makeNode(double, double);
    node makeCharacterNode(char);
    linkedList createList();
    
    /*
    int main(){                                      //?
        linkedList two;
       node v=makeNode(10,3);
       node i=makeNode(4,2);
       node c=makeNode(7,1);
       node t=makeNode(1,0);
       two.addNode(v);
       two.addNode(i);
       two.addNode(c);
       two.addNode(t);
       cout<<two.evaluate(2);
    
        
        
        system("PAUSE");
            return 0;
    }
    
    */
    //functions declared here.
    
    
    linkedList::linkedList(){
                             current=NULL;
                             head=makeNode(0,0);
                             length=0;
                             }
    
    void linkedList::addNode(node toAdd){
         if(length==0){
                       head = toAdd;
                       length++;}
         else{
         transverse();
         current->next=&toAdd;
         length++;
         }
         current=&head;
         }
    
    double linkedList::evaluate(double a){//This is really dumb.
           //cout<<current->coff<<endl;
           current=&head;
           double sum=0;
           
           while(current->next!=NULL){
           sum+=current->coff*pow(a,current->exp);
           current=current->next;
           }
           sum+=current->coff*pow(a,current->exp);
           return sum;
           }
    
    int linkedList::returnLength(){
        return length;
    }
    
    node linkedList::returnCurrent(){
         return *current;
         }
    
    void linkedList::transverse(){
         while(current->next!=NULL){
                                    current=current->next;
         }}
         
    void linkedList::incrementExponents(){
         current=&head;
         while(current->next!=NULL){
                                    current->exp++;
                                    current=current->next;
         }
         current->exp++;
         }
    linkedList linkedList::convertToNumbers(linkedList poly){
               linkedList numbers;
               linkedList subnumbers;
               
               double numbscoff;
               double numbsexp;
               int plusOrMinus=1;
               int subcreation=0;
               char shownHere;
               
               
               while (poly.returnCurrent().next!=NULL){
                     shownHere=poly.returnCharacter();
                                                      if ((int)shownHere>47&&(int)shownHere<58){
                                                      
                                                      subcreation=(int)shownHere-48;
                                                      subnumbers.addNode(makeNode(subcreation, -1));
                                                      subnumbers.incrementExponents();
                                                     }
                                                     
                                                     else if(shownHere=='x'||shownHere=='X'){
                                                          numbscoff=subnumbers.evaluate(10);
                                                          numbscoff*=plusOrMinus;
                                                          subnumbers.deleteList();
                                                                                          }
                                                     else if(shownHere=='^'){
                                                          //does nothing
                                                                             }
                                                     else if(shownHere=='+'){
                                                          numbsexp=subnumbers.evaluate(10);
                                                          numbers.addNode(makeNode(numbscoff,numbsexp));
                                                          subnumbers.deleteList();
                                                          plusOrMinus=1;
                                                                             }
                                                     else if(shownHere=='-'){
                                                          numbsexp=subnumbers.evaluate(10);
                                                          numbers.addNode(makeNode(numbscoff,numbsexp));
                                                          subnumbers.deleteList();
                                                          plusOrMinus=-1;}
                                                          
                                                     else cout<<"you put something in wrong."<<endl;
                                                     poly.setCurrent(poly.returnCurrent().next);
                                                     
               }
               
               return numbers;
               }
    char linkedList::returnCharacter(){
         return current->p;
         }
    
    void linkedList::integrate()
         {
         current=&head;
         while(current->next!=NULL){
         current->coff=current->coff/current->exp;
         current->exp--;
         current=current->next;
                                   }
         current->coff=current->coff/current->exp;
         current->exp--;
         }
    
    void linkedList::setCurrent(node* a){
         current=a;
         }
    void linkedList::deleteList(){//Is this doing what I think its doing?
         current=&head;
         node* temp;
         while(current->next!=NULL)   {
         temp=current->next;
         current=temp;
         delete current;
                                     }
         head.coff=0;
         head.exp=0;
                     }
    void linkedList::displayCharacterList(){
         current=&head;
         while(current->next!=NULL){
         cout<<current->p;
         current=current->next;
         }
         cout<<current->p;
                                   }
    void linkedList::displayTripleList(){
         current=&head;
         cout << "Head";
         system("PAUSE");
         while(current->next != NULL){  //Supererror
         display(current->dunce);
         cout << "Node";
         system("PAUSE");
         current=current->next;
         }
         cout << "Node";
         system("PAUSE");
         display(current->dunce)
         
         
    /*orderedTriple linkedList::sumForces(orderedTriple test){
                  current=&head;
                  orderedTriple forces;
                  while(current->next!=NULL){
                                             forces+=addForce(evalForce(current,test),forces);
                                             current=current->next;
                                             }
                  return forces;
                  }*/
                  /*
    orderedTriple linkedList::rungeKutta(orderedTriple test){
                 orderedTriple Rachy;
                  Rachy=sumForces(test);
                  Rachy+=sumForces(
    */
                                      
    //end of linkedList functions
    
    
    
    node makeNode(double coefficient, double exponent){
         node newNode;
         orderedTriple empty;
         newNode.coff=coefficient;
         newNode.exp=exponent;
         newNode.next=NULL;
         newNode.dunce=empty;
         newNode.p='t'; //We'll let T stand for nothing. It gives me an error to do ''.
         return newNode;
         }
    node makeNode(orderedTriple Rachel) {
         node newNode;
         newNode.coff=0;
         newNode.exp=0;
         newNode.p='t';
         newNode.dunce = Rachel;
         newNode.next = NULL;
         return newNode;
         }
    
    node makeCharacterNode(char a){ //This function allows me to adapt the linkedList class to the polynomial
         orderedTriple empty;
         node newNode;              //  which the user will input.
         newNode.coff=0;
         newNode.dunce=empty;
         newNode.exp=0;
         newNode.p=a;
         newNode.next=NULL;
         return newNode;
         }
         
    linkedList createList(){
               linkedList toBeReturned;
               node b;
               char polynomial;
               while(polynomial!=';'){
               cin>>polynomial;
               b=makeCharacterNode(polynomial);
               if(polynomial!=';')
               toBeReturned.addNode(b);
                                   }
               }
    
    //the function below will take in a polynomial and make it nodes and linked lists.
    
    
    linkedList fetchSpace(){
        ifstream coming ("dataset.txt");
        linkedList spaceStation;
        int n=1; // tells how far past a decimal point you are
        bool hitDecimal=false;
        orderedTriple toBeAdded;
        double upcomingValue=0;
        char nextChar;
        if(coming.is_open()){
        while(!coming.eof()){
                             coming>>nextChar;
        coming>>nextChar; //skips opening parenthesis
        if(coming.eof()) break;
        upcomingValue=(int)nextChar-48;
        do{
              coming>>nextChar;
              if(nextChar=='.')hitDecimal=true;
              if(hitDecimal==false&&nextChar!=','){
                                upcomingValue*=10;
                                upcomingValue+=(int)nextChar-48;}
    
        else if (nextChar!='.'&&nextChar!=','){
        upcomingValue+=((int)nextChar-48)*pow(10,-n);
        n++;
            }
        }while (nextChar!=',');
        n=1;
        hitDecimal=false;
        toBeAdded.setx(upcomingValue);
        upcomingValue=0;
        do{
              coming>>nextChar;
              if(nextChar=='.')hitDecimal=true;
              if(hitDecimal==false&&nextChar!=','){
                                upcomingValue*=10;
                                upcomingValue+=(int)nextChar-48;}
    
        else if (nextChar!='.'&&nextChar!=','){
        upcomingValue+=((int)nextChar-48)*pow(10,-n);
        n++;
            }
        }while (nextChar!=',');
        n=1;
        hitDecimal=false;
        toBeAdded.sety(upcomingValue);
        upcomingValue=0;
        
        do {
              coming>>nextChar;
              if(nextChar=='.')hitDecimal=true;
              if(hitDecimal==false&&nextChar!=')'){
                                upcomingValue*=10;
                                upcomingValue+=(int)nextChar-48;}
    
        else if (nextChar!='.'&&nextChar!=')'){
        upcomingValue+=((int)nextChar-48)*pow(10,-n);
        n++;
            }
        }while (nextChar!=')');
        n=1;
        hitDecimal=false;
        toBeAdded.setz(upcomingValue);
        upcomingValue=0;
        spaceStation.addNode(makeNode(toBeAdded));
    } 
    }
    else cout<<"fileerror";
    coming.close();
    return spaceStation;
    }
    
    orderedTriple evalForce(node Emily, orderedTriple test){ //this orderedTriple will be a vector.
    double rSquare=pow(Emily.dunce.returnx()-test.returnx(),2)+pow(Emily.dunce.returny()-test.returny(),2);
    //find n such that (ny)^2+(nx)^2=r^2
    double why=(test.returny()-Emily.dunce.returny());
    double ehx=(test.returnx()-Emily.dunce.returnx());
    double n=rSquare/(pow(why,2)+pow(ehx,2));
    why*=n;
    ehx*=n;
    orderedTriple Gigi(ehx, why, 0); // Written with ihats and jhats
    return Gigi;
    }
    
    orderedTriple addForce(orderedTriple first, orderedTriple second){
                  first.setx(first.returnx()+second.returnx());
                  first.sety(first.returny()+second.returny());
                  return first;
                  }
                  
    
    
    int main(){
        orderedTriple k;
        node n=makeNode(k);
        cout<<n.dunce.returnx();
        linkedList j;
        
        k.setx(1);
        k.sety(1);
        k.setz(1);
        j.addNode(makeNode(k));
        
        k.setx(2);
        k.sety(2);
        k.setz(2);     
        j.addNode(makeNode(k));    
        
        k.setx(4);
        k.sety(4);
        k.setz(4);   
        j.addNode(makeNode(k)); 
        //linkedList p=fetchSpace();
        j.displayTripleList();
            
        system("PAUSE");
        return 0;
    }

    If anyone could tell me how to fix my bug, it would be greatly appreciated.

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Annoying linked list error

    Quote Originally Posted by doo_grammar_good View Post
    I'm trying to write code that takes can read in ordered triples from a file, store them in a linked list and spit them out again, but I get a strange error.
    That error is not "strange", as it means that you are mishandling memory or you have a memory overwrite.
    I basically took a linked list that was on my computer and tried to modify it,
    Why not just learn to use the std::list class (which is a linked list class) which already works, instead of trying to write and maintain your own linked list?

    That's the risk you take when you attempt to code your own container classes instead of using container classes that already exist, and that risk is that any bugs you encounter, you'll have to fix them.
    Code:
                  
     class string {
    Do not call your class "string". There is already a std::string class in C++, and creating your own class called "string" will possibly confuse the compiler, if not, others using your code. As a matter of fact, your string class is not necessary, as std::string does everything that code does.

    To add, your linked list class has memory leaks (no destructor coded to clean up the list). There can be other errors that are not visible just by eyeballing the code.
    If anyone could tell me how to fix my bug, it would be greatly appreciated.
    I can give you one way to fix the bug, and that is to take the code you have now, learn std::list, learn std::string, and rip out the old code and replace it with these classes. Not only will the code work after doing that, it will be at least half the size of the code you have now, you would have learned how to use standard containers, and you would have learned how to take unsafe code and made it safe by using these standard classes.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; March 18th, 2011 at 12:47 AM.

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Annoying linked list error

    Start here:
    Code:
    #include <iostream>
    #include <string>
    #include <list>
    #include <cmath>
    
    class orderedTriple
    {
    private: double xcoord, ycoord, strength;
    public: 
        orderedTriple(){xcoord=ycoord=strength=0;}
        orderedTriple(double x, double y, double z){
            xcoord=x; ycoord=y; strength=z;}
        orderedTriple getForce(double x, double y){
            double a,b,c;
            a=x-xcoord; b=y-ycoord; c=strength/sqrt(pow(a,2)+pow(b,2));
            orderedTriple force(a,b,c);
            return force;
        };
        void setx(double x){xcoord=x;}
        void sety(double x){ycoord=x;}
        void setz(double x){strength=x;}
        double returnx() const {return xcoord;}
        double returny() const {return ycoord;}
        double returnz() const {return strength;}
    };
    
    void display(const orderedTriple& Lynn)  {
        std::cout<<"("<<Lynn.returnx()<<","<<Lynn.returny()<<","<<Lynn.returnz()<<")";
    }             
    
    struct node{
        orderedTriple dunce;
        double coff;
        double exp;
        char p;
    };
    
    typedef std::list<node> linkedList;
    
    node makeNode(double coefficient, double exponent)
    {
        node newNode;
        orderedTriple empty;
        newNode.coff=coefficient;
        newNode.exp=exponent;
        newNode.dunce=empty;
        newNode.p='t';        
        return newNode;
    }
    
    node makeNode(const orderedTriple& Rachel) 
    {
        node newNode;
        newNode.coff=0;
        newNode.exp=0;
        newNode.p='t';
        newNode.dunce = Rachel;
        return newNode;
    }
    
    void displayTripleList(const linkedList& theList)
    {
        linkedList::const_iterator it = theList.begin();
        while (it != theList.end( ) )
        {
            display(it->dunce);
            ++it;
        }
    } 
    using namespace std;
    
    int main()
    {
        orderedTriple k;
        node n=makeNode(k);
        cout<<n.dunce.returnx();
        linkedList j;
    
        k.setx(1);
        k.sety(1);
        k.setz(1);
        j.push_back(makeNode(k));
    
        k.setx(2);
        k.sety(2);
        k.setz(2);     
        j.push_back(makeNode(k));    
    
        k.setx(4);
        k.sety(4);
        k.setz(4);   
        j.push_back(makeNode(k)); 
        displayTripleList(j);
        return 0;
    }
    
    Output:
    (1,1,1)(2,2,2)(4,4,4)
    This code properly compiles and runs main(). Note that there are no pointers, no code to "add a node", no code to remove the nodes from the list, etc. The reason is that all of that code is there already in the code above. The std::list class is a linked list, the code to add a node is the push_back() function, the code to remove the nodes when done is the std::list destructor, etc. The code to traverse the list from the first to last node is that while() loop using an iterator.

    So in other words, that entire code above does more (and correctly with no bugs) than half of your old code. You won't get segmentation faults (unless you built the program incorrectly), and you can go on with the next step knowing that you have a solid foundation to work from.

    Now that you have the code above, take the missing functions, and rewrite them to work with linkedList. In other words, those other functions are no longer part of the linkedList class, they should be standalone and take a linkedList as an argument. Then you can take that code and make it more object-oriented by building a class around it -- but you don't attempt to do this until you get code that works.

    Or you can keep struggling with your own code and attempt to debug it. Again, the responsibility you take on for yourself when you use your own home-made containers is that you know how to debug them when things go wrong. With the code above, you have no such issues.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; March 18th, 2011 at 12:46 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured