Linked list issues

Posted on 2004-11-05
Last Modified: 2013-12-14
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.

Question by:savante
    LVL 19

    Accepted Solution

    >> 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.


    LVL 17

    Assisted Solution

    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.
    LVL 3

    Assisted Solution

    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
    LVL 19

    Expert Comment

    Three way split between all participants.

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Live - One-on-One C++ Help from Top Experts

    Solve your toughest problems, fast.
    C++ experts are online now and ready to help you.

    C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (…
    Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project ( automates most of the tasks discussed in this article. You can even fin…
    THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
    The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…

    760 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    15 Experts available now in Live!

    Get 1:1 Help Now