Linked list issues

It's probably been 3 years since I've worked with a linked list, and as a result, I'm sure my error is very basic, but I just can't figure it out.  I've been provided with my teacher's code, and I did the best I could, but it still provides a problem.

Basically, I've written an interpreter for a language he's given us.  I'm having problems with the parser, though.  The tokenizer works great.  The input I'm trying to deal with is :

program int X , Y , XY;

It skips over the program fine, no problem.  The next part (int X , Y, XY; ) is an id-list, and that's an issue.  We have to check to first make sure the Id is not already declared before we use the constructor, otherwise, it shouldn't be a part of the list.  The program works great for a bit, as it reads in the X, and sets it to the first node.  Then, the second time through, the parseNode procedure has an error in the list.  I'm thinking it's a result of me building the linked list incorrectly, but I've bolded the line that causes an issue.  Down below that is the debug output I've added.  

void Idlist::parse()
                  cout << "Parsing id-list";
                  int tokNo, tokVal;
                  char idName[10];
                  ParseTree token;
                  token.getToken(tokNo, tokVal, idName);

                  cout << idName;
//outputs X the first time through, Y the second
                  Id2* id2;
                  id = (id2->parseId());
                  token.getToken(tokNo, tokVal, idName);
                  if (tokNo == COMMA)

                        cout << "Choosing second alternative";

So, in this section, basically, the token 'int' is skipped, leading to an id.  The id is in the current token, and getToken reads it in (does not skip it).  Then, the X is parsed correctly, returning back.  It skips over the X, then getToken returns that it is a comma and there are more values, so it recursively calls itself.  The second time through, it starts off by skipping the comma, then the getToken returns the value Y.  In parseID, below, there becomes problems.

#include "Id2.h"
#include "ParseTree.h"

#include <iostream>

class ParseTree;
Id2::Id2(char n1[10], Id2* nid) {
           // private constructor; used by parseId()
           strcpy(name, n1);
           decl = false; init = false; nextId = nid; }

Id2* Id2::parseId() {

      cout << "Parsing ID"; //prints out twice
          char n2[10]; Id2* candId;

              int tokNo, tokVal;

              ParseTree token;

              token.getToken(tokNo, tokVal, n2);

              if (firstId != NULL)
                    candId = Id2::firstId;
                    cout << "Before for"; //This  prints out twice
          for(candId = Id2::firstId; nextId != NULL; candId = nextId)
                    cout << "in loop";
                         //This line never prints, and on the second go round, it should.
               if (strcmp(n2, candId->idName()) == 0) return candId;

          // if not, create a new Id, make that the firstId, and return
          // that.
          candId = new Id2(n2, Id2::firstId);
              Id2::firstId = candId;
              cout << "Id name = " << candId->idName();
          return candId;
int Id2::getIdval() {
      if (!init)
            cout<< "error; uninitialized var";
                        return currVal; }
void Id2::setIdval(int x) { init = true; currVal = x; }
char* Id2::idName() { return name; }

The error is simply an exception error, and when I run it through the Windows debugger, it occurs at the for line in parseId.  The contId does get set to firstId, which is good , but 'this' is set to 0xcccccc.   Therefore, I think it's a problem with next, as it never enters the for loop (and prints out "In for loop") .  I tried earlier using static arrays for the ID names, values, and if they were initialized at all, but it didn't work, as the static variables had problems with references in the member functions.

          for(candId = Id2::firstId; nextId != NULL; candId = nextId)  is the line where it's erroring, then.   Since candId is set to Id2::firstId, that's not the issue.  It's with either one of the nextId statements, leading me to believe (very possibly) that I set it up wrong.

Thanks in advance for your help.  Any insight at all would be helpful.. I've been staring at my code for the last 2 days and I've come to no conclusions.

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

>> for(candId = Id2::firstId; nextId != NULL; candId = nextId)  is the line where it's erroring, then.  

What on earth is this supposed to do ?!  A for loop has the following form:

for (<initial state>; <test of condition>; <altering state>)
  // action

You have the first two correct, but the third, " candId = nextId" is completely wrong.  This will just run into infinity, since the variable in your testing condition, nextID, which you are testing against NULL, is never altered.  A more suitable implementation would be

for(candId = Id2::firstId; nextId != NULL; nextId++)

which loops through all values of nextID until we hit one that is NULL.

But even this is not fully conventional.  You should be initialising nextID in the first component of the for loop - you are stating

candId = Id2::firstId

candId has no part in the rest of the loop, so why include it ?  

Now I don't know what the overall aim here is, but it should be clear where you are going wrong.  So hopefully you can adjust your for loop accordingly.



Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
mrwad99 is right.

Technically, there's nothing to stop you from defining an operator=, which takes an non-const reference parameter, which it alters, like the following:

#include <iostream>

template<typename T> class depletor {
      T t;
public:      depletor(T& t) : t(t--) {}
      depletor<T>& operator=(T& depleted) /* Highly irregular operator= alters the operand!! */
            t = depleted--;
            return *this;
      operator T () const {
            return t;

int main()
      int next = 10;
      for (depletor<int> d = next;next;d = next)
            std::cout << "Depletor is " << static_cast<int>(d) << '\n';

But this is very unconventional and should be avoided for that reason. It is no accident that IOStreams use insertion operators rather than operator=. You shouldn't expect operator= to alter its parameter.
Discussion of the loop aside, there is also a problem with your main().

               Id2* id2;
               id = (id2->parseId());

id2 is uninitialize.

Did you mean to say

    Id2* id2 = new Id2(idName, NULL);

and then delete id2 later on?


- Frank
Three way split between all participants.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.