Thread: Noobish problem

  1. #1
    Registered User
    Join Date
    Jul 2005
    Posts
    23

    Talking Noobish problem

    Hello, I am new here(but I have lurked off and on). I finally decided to post about this. I was trying to get used to using linked list type structures and was trying to make one, but I did something major wrong here.

    Code:
    #include <iostream.h>
    class mylinky
    {
     private:
     static mylinky *first;
     mylinky *next;
     char content;
     public:
     mylinky(char input='p')
     {
      if (first==0)
         {
          first=this;
          content=input;
          next=0;
         }
      else
         {
          mylinky *finger;
          finger=first;
          while(!(finger->next==0)){finger=finger->next;};
          first=this;
          next=0;
         };
     }
     void printContents(void)
     {
      mylinky *finger;
      finger=first;
      while(!(finger==0))
      {
       cout<<finger->content<<".";
       finger=finger->next;
      };
     }
    };
    
    int main (void)
    {
     system("PAUSE");
    }
    As this is, it compiles fine. However, if I change main to
    Code:
    int main (void)
    {
     mylinky test = mylinky('q');
     system("PAUSE");
    }
    I get [Linker error] undefined reference to `mylinky::first' about 5 times. I know I am probably doing something fairly wrong here. I was tempted not to post this at all, but I figured I would give it a shot.

  2. #2
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    First, welcome to the board and congratulations on asking a reasonable question, posting pertinent code, indenting your code, and using code tags to post code to the board. I'd say you're off to a good start!


    I would step back from the code and think about linked lists a little bit more. I think of linked lists in C++ as a group of objects linked together. That means that the linked list is one object and each of the links is an object in and of itself. Thus, I would break your code into two different classes, one for the link objects and one for the list.
    Code:
    struct MyLink
    {
       char data;
       MyLink * next;
    };
     
    class MyList
    {
       public: 
    	 MyLink * first;
    	 MyList() : first(NULL) {};
    	 ~MyList() { //code to release memory allocated by new operator in addLink;}
    	 void addLink(char);
    };
     
    MyList::addLink(char ch)
    {
       //develop a new MyLink object to add to this list
       MyLink* newLink = new MyLink();
       newLink->data = ch;
       newLink->next = NULL;
     
       //code to add newLink to this list
       if(first == NULL)
    	 first = newLink;
       else
    	 //code to add newLink to this list if this list is not empty
    }
     
    int main()
    {
       MyList mylist;
       myList.addlink('y');
    }
    In your code you are trying to do everything within a single class and getting your feet crossed.
    You're only born perfect.

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You don't need semicolons on the end of functions, only classes.

    Does this compile?
    Code:
    mylinky test('q');
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    > static mylinky *first;
    You have first declared as a static member of mylinky, which means every instance of mylinky shares the same first. If this is not what you want, then remove the static:
    mylinky *first;

    Otherwise, in addition to declaring them, you must define any static members of your class at some point.
    Code:
    mylinky *mylinky::first = NULL;

  5. #5
    Registered User
    Join Date
    Jul 2005
    Posts
    23

    Ok, I've gotten further.

    I have gotten a lot further, and I appreciate the help. This is definately something I needed to do. Special thanks for the bit about initializing Static members, even though it no longer applies to this problem(although I would like to retry doing what I did the first time once I get this other way of doing it worked out.)

    Code:
    #include <iostream>
    struct myNode
    {
     char value;
     myNode * next;
    };
    class myNodeList
    {
     private:
     myNode * first;
     myNode * index;
     public:
     myNodeList() : first(0),index(0){};
     ~myNodeList()
     {
      myNode * finger;
      finger=first;
      while(!(finger==0))
      {
       myNode * nullnext;
       nullnext=finger->next;
       delete finger;
       finger = nullnext;
      }
     }
     void addNode(char value)
     {
      myNode * newNode = new myNode();
      newNode->value = value;
      newNode->next = 0;
      if (first==0){first=newNode;}
      else 
      {
       myNode * finger;
       finger=first;
       while(!(finger->next==0)){finger=finger->next;};
       finger->next = newNode;
      }
     }
     char eachNode(void)
     {
      char ret;
      if (index=0){index=first;};
      if (!(index=0))
      {
       ret = index->value;
       index=index->next;
      }
      else
      {return 0;};
     }
     char printNodeList(void)
     {
      myNode * finger;
      finger=first;
      while(!(finger==0)){printf(&finger->value);finger=finger->next;};
     }
     int nodeCount(void)
     {
      myNode * finger;
      int count;
      finger=first;
      while(!(finger==0)){++count;finger=finger->next;};
      return count;
     }
    };
    int main(void)
    {
     myNodeList nodez;
     nodez.addNode('y');
     nodez.addNode('a');
     nodez.addNode('y');
     nodez.addNode('!');
     nodez.printNodeList();
     printf("%d",nodez.nodeCount());
     delete &nodez;
     system("PAUSE");
    }
    Seems pretty good so far, but nodeCount is returning huge numbers, any idea why it might be doing that? EDIT:Found it. Me and my silly simpler language experiances poisoning my brain I wasn't starting Count out with a value so it had some silly giant number in it from the get-go. Well, I suppose I still have the question about the destructor, so I'll leave it

    EDIT:Oh, and while I am posting, is my destructor cleaning up completely or is it leaking?
    Last edited by tol; 07-21-2005 at 01:40 PM.

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >Seems pretty good so far, but nodeCount is returning huge numbers, any idea why it might be doing that?

    > int count;
    Because count's never initialized?

  7. #7
    Registered User
    Join Date
    Jul 2005
    Posts
    23

    Thanks Swoopy

    Thanks, figured that out a split second before I read your post. I need to get the assumptions beat out of me on stuff like that.

    I need some constructive criticism, if any, on my destructor as I am not 100% clear on how they work.

  8. #8
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >Oh, and while I am posting, is my destructor cleaning up completely or is it leaking?
    At first glace it looks good. Perhaps someone else can verify it.

  9. #9
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >on my destructor as I am not 100% clear on how they work.
    As you probably know, they get called whenever an object goes out of scope (at the end of main() in your case). Or if the object is allocated with new, when delete is called on that object.

    There's quite a few here that really know linked lists, and can probably comment on your destructor. It's possible it could be written more concisely, but certainly looks good to me.

  10. #10
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    > delete &nodez;
    And looking at your main(), this is incorrect. Only use delete if the object is created with new. Your destuctor will be called at the end of main().

    So if you had:
    Code:
     myNodeList *nodez;
    
     nodez = new myNodeList;
    You would need a delete. But making this a pointer is entirely unnecessary.

  11. #11
    Registered User
    Join Date
    Jul 2005
    Posts
    23

    Thanks again.

    Ah ok. Now that makes more sense with New and Delete. So what it boils down to is that my variable is actually an entire myNodeList object, and not just a type of pointer to it.

    This is the current version of my code (sorry for such a long thread).

    Code:
    #include <iostream>
    
    class myNodeList
    {
     private:
     struct myNode
     {
      char value;
      myNode * next;
     };
     myNode * first;
     myNode * index;
     public:
     myNodeList() : first(0),index(0){}
     ~myNodeList()
     {
      myNode * finger;
      finger=first;
      while(!(finger==0))
      {
       myNode * nullnext;
       nullnext=finger->next;
       delete finger;
       finger = nullnext;
      }
     }
     void addNode(char value)
     {
      myNode * newNode = new myNode();
      newNode->value = value;
      newNode->next = 0;
      if (first==0){first=newNode;}
      else 
      {
       myNode * finger;
       finger=first;
       while(!(finger->next==0)){finger=finger->next;}
       finger->next = newNode;
      }
     }
     char eachNode(void)
     {
      char ret;
      if (index=0){index=first;}
      if (!(index==0))
      {
       ret=index->value;
       index=index->next;
      }
      else
      {ret= 0;}
      return ret;
     }
     char printNodeList(void)
     {
      myNode * finger;
      finger=first;
      while(!(finger==0)){printf(&finger->value);finger=finger->next;};
     }
     int nodeCount(void)
     {
      myNode * finger;
      int count=0;
      finger=first;
      while(!(finger==0)){++count;finger=finger->next;}
      return count;
     }
    };
    int main(void)
    {
     myNodeList nodez;
     nodez.addNode('y');
     nodez.addNode('a');
     nodez.addNode('y');
     nodez.addNode('!');
     nodez.printNodeList();
     printf("\n");
     for (int index=0;index<nodez.nodeCount();++index)
     {
      printf("%d.",nodez.eachNode());
     }
     printf("\n");
     system("PAUSE");
    }
    If the length of this thread or my asking questions as-I-go breaks any rules(I don't think it does, but it might) feel free to lock or delete this thread, otherwise I will probably have a few more questions as I go.

    I am still tinkering with it but, does anyone have any idea why eachNode won't spit out anything but zero? I am trying to use eachNode to build up a sort of "FOR...EACH...NEXT" style where I can step and process each member, allow them to delete themselves, etc.

    EDIT: Woops, it was an == != = problem
    Last edited by tol; 07-21-2005 at 02:17 PM.

  12. #12
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Code:
    >  if (index=0){index=first;}
    Notice anything? By the way, there's a way to turn on warnings about this on most compilers. I'm using Dev-C++ and haven't figured out how yet, but I'm sure there's a way.

    EDIT: problem solved

  13. #13
    Registered User
    Join Date
    Jul 2005
    Posts
    23

    Me too.

    Dev C++ here too. Let me know if you find out, and I'll do the same.

    Well, I have another problem. As I said before, I am trying to build up to using a FOR...EACH...NEXT style, and I am taking steps in that direction here. It compiles with zero errors, but then it crashes when run.

    Code:
    #include <iostream>
    
    class myNodeList
    {
     private:
     struct myNode
     {
      char value;
      myNode * next;
     };
     myNode * first;
     myNode * index;
     public:
     myNodeList() : first(0),index(0){}
     ~myNodeList()
     {
      myNode * finger;
      finger=first;
      while(!(finger==0))
      {
       myNode * nullnext;
       nullnext=finger->next;
       delete finger;
       finger = nullnext;
      }
     }
     void addNode(char value)
     {
      myNode * newNode = new myNode();
      newNode->value = value;
      newNode->next = 0;
      if (first==0){first=newNode;}
      else 
      {
       myNode * finger;
       finger=first;
       while(!(finger->next==0)){finger=finger->next;}
       finger->next = newNode;
      }
     }
     void eachNode(void)
     {
      if (index==0){index=first;}
      if (!(index==0)){index=index->next;}
     }
     char eachNode_getValue(void)
     {
      return index->value;
     }
     char printNodeList(void)
     {
      myNode * finger;
      finger=first;
      while(!(finger==0)){printf(&finger->value);finger=finger->next;};
     }
     int nodeCount(void)
     {
      myNode * finger;
      int count=0;
      finger=first;
      while(!(finger==0)){++count;finger=finger->next;}
      return count;
     }
    };
    int main(void)
    {
     myNodeList nodez;
     nodez.addNode('y');
     nodez.addNode('a');
     nodez.addNode('y');
     nodez.addNode('!');
     nodez.printNodeList();
     printf("\n");
     for (int index=0;index<nodez.nodeCount();++index,nodez.eachNode())
     {
      printf("%c",nodez.eachNode_getValue());
     }
     printf("\n");
     system("PAUSE");
    }

  14. #14
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    I like your FOR...EACH idea. Now you have two problems. One in eachNode():
    Code:
    > void eachNode(void)
    > {
    >  if (index==0){index=first;}
    >  if (!(index==0)){index=index->next;}
    > }
    This should really be:
    Code:
     void eachNode(void)
     {
      if (index==0){index=first;}
      else {index=index->next;}
     }
    Otherwise you skip the first node.
    And then there's your fancy for-loop. It's stepping one too far. Try instead:
    Code:
     for (int index=0;index<nodez.nodeCount();++index)
     {
      nodez.eachNode();
      printf("%c",nodez.eachNode_getValue());
     }

  15. #15
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >printf(&finger->value);
    And I believe this would be better written:
    printf("%c",finger->value);
    as printf() is expecting a null-terminated char array for the first parameter.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help understanding a problem
    By dnguyen1022 in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2009, 04:21 PM
  2. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  3. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  4. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  5. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM