I am kind of new to c++, i usually code in java and php. This is a program that is supposed to read in an input file with very strict syntax that will either create a new stack/queue (implemented subclasses of simpleList), or push a value onto one of those stacks/queues assuming it exists, or it will pop a value from them, again, assuming they exist.
the acceptable types are int, string, double, therefore templates are used. the first letter of the name of each stack/queue has to be either i,s,d.
example:

create i99 stack
push dHelloWorld -.0343
pop s55


i have most of it working, but I got to segfaults, I've been debugging for hours and I have no idea. the debugger traces the problem back to void setnext(Node *t)....

any help would be much appreciated, below is my code

#include <iostream>
#include <string>
#include <list>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

using namespace std;
//with a lot of help from the internet and the textbook
template <typename Object>
class simpleList{

   private:
       string name;
       int Size;
               class Node
                {
                   Object data;
                   Node *next;

                       public:

                       Node ( Object d, Node *n )
                        {
                            data = d;
                            next =n;
                        }
                               Object retval()
                               { return data; }
                               Node *retpoint()
                               { return next; }
                               void setdata(Object t)
                               { data = t; }
                               void setnext(Node *t )
                               { next = t; }
       };

   public:

       string getName()
       {
           return name;
       }
           Node *head;
           Node *tail;

       simpleList()
       {
                Object *d = new Object; //dummy value
                head = new Node(*d, NULL);
                head =  tail;
       }

       int size()
       {        return Size;}

        void changeSize(int i)
               { Size = i; }

       virtual void push(Object x) = 0; //pushes to the front for both queue and stack, the difference will lie in how they are removed};
               virtual Object pop() = 0;

       protected: // change all the -> to Node functions
        void push_front(Object x)
       {
          Node *p = new Node(x, head->retpoint());
          Size++;
          head->setnext(p);
       }

       void push_back(Object x)
       {
           Node *p = new Node(x, NULL);

           if(tail == head)
               head->setnext(p);
            else
                tail->setnext(p);

           Size++;
           tail = p;
       }
               Object remove()
               {
                       Node *p = head->retpoint();
                       Size--;
                       head->setnext( p->retpoint()) ;
                       Object data = p->retval();
                       delete p;
                       return data;
               }
               void changeName(string s)
               {
                       name = s;
               }
};

template<typename Object>
class Stack : public simpleList<Object>
{
       private:

       public:
               Stack(string naam)
       {
                   simpleList<Object>::changeName(naam);
                   //simpleList<Object>::head = new Node(*d, tail);
                                       simpleList<Object>::tail = NULL;
                                       simpleList<Object>::changeSize(0);
       }
               void push(Object x)
               {
                       push_front(x);
               }
               Object pop()
               {
                       return simpleList<Object>::remove();
               }
};

template<typename Object>
class Queue : public simpleList<Object>
{
       private:

       public:
               Queue(string naam)
       {
                   simpleList<Object>::changeName(naam);
                   //simpleList<Object>::head = new Node(*d, tail);
                                       simpleList<Object>::tail = NULL;
                                       simpleList<Object>::changeSize(0);
       }
               void push(Object x)
               {
                       push_back(x);
               }
               Object pop()
               {
                       return simpleList<Object>::remove();
               }
};

template <typename Object>
simpleList<Object> * search(list<simpleList<Object> *> a, string name)
{
           int index=0;
             for(class list<simpleList<Object> *>::iterator ci = a.begin(); ci !=a.end(); ++ci)
             {
                  index++;

                   if((*ci)->getName().compare(name) == 0)
                       return *ci;
             }

               if(index == a.size())
                   return NULL;
};



int main () {

 list<simpleList<int> *> listSLi; //all the integer stacks or queues
 list<simpleList<double> *> listSLd; //all the double stacks or queues
 list<simpleList<string> *> listSLs; //all the string stacks or queues

 string line;
 char file[50];
 string str1 = "pop";

 cout << "write a filename!\t";
 cin >> file;

 //simpleList<int> *sl = new Stack<int>("ihello");
 //listSLi.push_back(sl);

 ifstream myfile (file);
 if (myfile.is_open())
 {
   while (! myfile.eof() )
   {
     getline (myfile,line);
     cout << line << endl; //remove

       string cmd = line;

       if(line.substr(0,3).compare(str1) < 0) // create
       {
           size_t pos = line.find_last_of(' ');
           string adt = line.substr(pos+1,line.size() -1); //stack or queue
           line.resize(pos);
           size_t pos2 = line.find_first_of(' ');
           string name = line.substr(pos2,line.size() -1); //name of stack or queue
           char type = name.at(1);//i,d,s

               if(adt == "stack")
               {
                    if(type == 'i')
                    {
                        simpleList<int> *pSLi = new Stack<int>(name);
                        if(listSLi.size() == 0)
                        {
                            listSLi.push_front(pSLi);
                            cout<<name<<"Added"<<endl;
                        }
                        else{
                        if(search(listSLi,name) != NULL)
                            cout<<"Error:this name already exists"<<endl;
                        else
                        {
                            listSLi.push_front(pSLi);
                            cout<<name<<"Added"<<endl;
                        }
                        }
                    }
                    else if(type == 'd')
                    {
                       simpleList<double> *pSLd = new Stack<double>(name);
                        if(listSLd.size() == 0)
                        {
                            listSLd.push_front(pSLd);
                            cout<<name<<"Added"<<endl;
                        }
                        else{
                        if(search(listSLd,name) != NULL)
                            cout<<"Error:this name already exists"<<endl;
                        else
                        {
                            listSLd.push_front(pSLd);
                            cout<<name<<" Added"<<endl;
                        }
                        }
                    }
                    else if(type == 's')
                    {
                        simpleList<string> *pSLs = new Stack<string>(name);
                        if(listSLs.size() == 0)
                        {
                            listSLs.push_front(pSLs);
                            cout<<name<<" Added"<<endl;
                        }
                        else{
                        if(search(listSLs,name) != NULL)
                            cout<<"Error:this name already exists"<<endl;
                        else
                        {
                            listSLs.push_front(pSLs);
                            cout<<name<<" Added"<<endl;
                        }
                        }
                    }
                }
               else if(adt == "queue")
               {
                    if(type == 'i')
                    {
                        simpleList<int> *pSLi = new Queue<int>(name);
                        if(listSLi.size() == 0)
                        {
                            listSLi.push_front(pSLi);
                            cout<<name<<" Added"<<endl;
                        }
                        else
                        {
                            if(search(listSLi,name) != NULL)
                                cout<<"Error:this name already exists"<<endl;
                            else
                            {
                                listSLi.push_front(pSLi);
                                cout<<name<<" Added"<<endl;
                            }
                        }
                    }
                    else if(type == 'd')
                    {
                       simpleList<double> *pSLd = new Queue<double>(name);
                        if(listSLd.size() == 0)
                        {
                            listSLd.push_front(pSLd);
                            cout<<name<<" Added"<<endl;
                        }
                        else{
                        if(search(listSLd,name) != NULL)
                            cout<<"Error:this name already exists"<<endl;
                        else
                        {
                            listSLd.push_front(pSLd);
                            cout<<name<<" Added"<<endl;
                        }
                        }
                    }
                    else if(type == 's')
                    {
                        simpleList<string> *pSLs = new Queue<string>(name);
                        if(listSLs.size() == 0)
                        {
                            listSLs.push_front(pSLs);
                            cout<<name<<" Added"<<endl;
                        }
                        else
                        {
                            if(search(listSLs,name) != NULL)
                                cout<<"Error:this name already exists"<<endl;
                            else
                            {
                                listSLs.push_front(pSLs);
                                cout<<name<<" Added"<<endl;
                            }
                        }
                    }
               }
       }
      else if(line.substr(0,3).compare(str1) ==  0) // pop
       {
           size_t pos = line.find_last_of(' ');
           string name = line.substr(pos,line.size() -1);
            char type = name.at(1); //i,s,d

            if(type == 'i')
            {
                if(listSLi.size() != 0)
                {
                    simpleList<int> *pLi = search(listSLi,name);
                    if(pLi == NULL)
                        cout<<"Error: this name does not exist"<<endl;
                    else if(pLi->size() == 0)
                        cout<<"Error: This list is empty!"<<endl;
                    else
                       cout<< pLi->pop()<<endl;
                }
                else
                    cout<<"Error: this name does not exist"<<endl;
            }
            if(type == 'd')
            {
                if(listSLd.size() != 0)
                {
                    simpleList<double> *pLd = search(listSLd,name);
                    if(pLd == NULL)
                        cout<<"Error: this name does not exist"<<endl;
                    else if(pLd->size() == 0)
                        cout<<"Error: This list is empty!"<<endl;
                    else
                       cout<< pLd->pop()<<endl;
                }
                else
                        cout<<"Error: this name does not exist"<<endl;
            }
            if(type == 's')
            {
                if(listSLs.size() != 0)
                {
                    simpleList<string> *pLs = search(listSLs,name);
                    if(pLs == NULL)
                        cout<<"Error: this name does not exist"<<endl;
                    else if(pLs->size() == 0)
                        cout<<"Error: This list is empty!"<<endl;
                    else
                       cout<< pLs->pop()<<endl;
                }
                else
                        cout<<"Error: this name does not exist"<<endl;
            }
       }
        else if(line.substr(0,3).compare(str1) >  0) // push
        {
            size_t pos = line.find_last_of(' ');
           string val = line.substr(pos+1,line.size() -1);
           char cval[val.size()];
           for(int i =0; i<val.size(); i++)
            cval[i] = val.at(i);

           line.resize(pos);
           size_t pos2 = line.find_first_of(' ');
           string name = line.substr(pos2,line.size() -1); //name of stack or queue
           char type = name.at(1);//i,d,s

            if(type == 'i')
            {
                if(listSLi.size() != 0)
                {
                    simpleList<int> *pSi = search(listSLi,name);
                    if(pSi == NULL)
                        cout<<"ERROR: This name does not exist!"<<endl;
                    else
                    {
                        int ival = atoi(cval);
                        pSi->push(ival);
                    }
                }
                else
                    cout<<"Error: this name does not exist"<<endl;
            }
            else if(type == 'd')
            {
                if(listSLd.size() != 0)
                {
                    simpleList<double> *pSd = search(listSLd,name);
                    if(pSd == NULL)
                        cout<<"ERROR: This name does not exist!"<<endl;
                    else
                    {
                        double dval = atof(cval);
                        pSd->push(dval);
                    }
                }
                else
                        cout<<"Error: this name does not exist"<<endl;
            }
            else if(type == 's')
            {
                if(listSLs.size() !=0)
                {
                    simpleList<string> *pSs = search(listSLs,name);
                    if(pSs == NULL)
                        cout<<"ERROR: This name does not exist!"<<endl;
                    else
                        pSs->push(val);
                }
                else
                    cout<<"Error: this name does not exist"<<endl;
            }
        }
}
   myfile.close();
 }
 else cout << "Unable to open file";

 return 0;
}

Recommended Answers

All 3 Replies

Are you sure that the code you've posted even compiles??
I've not looked at your code in great detail, but from briefly looking at it I've spotted a few obvious errors that shouldn't allow this code to compile, let alone run and segfault!

For starters there's your misuse of the 'class' keyword in the for loop at line 149. You aren't declaring a class here, you're creating an iterator. I would've expected this line of code to throw a compiler error. Remove the class keyword there, that should solve that problem.

Also at line 371 you're declaring a C-style char array, but it isn't using a constant value. This should be throwing an error at compile time too. Arrays in C/C++ require a fixed value for their size. Variable length arrays cannot be created in this manner. Besides, if you need a variable length array in C++ it is far better to use one of the std::library containers like std::string, std::vector, std::deque which can robustly do their own memory management (so you don't have to!).

In fact, actually looking at your code, you don't really need cval at all:
It's obvious that cval is a C-style char array copy of whatever is stored in val and val is a std::string. And the thing to bear in mind here is that the std::string class has a c_str() member function which returns a C-style char array.

So in other words, you can completely remove cval. Rip it out, it is completely unnecessary. Then where you use cval as a parameter to the calls to atoi (@ line 389) and atof (@ line 405) you can simply pass val.c_str() as a parameter instead.
e.g. @ line 389:

int ival = atoi(val.c_str());

I don't have a compiler handy ATM, so I can't test any of this. But try making the changes I've recommended and recompile and test your program.

Those changes should at least remove the syntax related errors, allowing the program to compile and run. If there are any further problems, by all means make another post.
As I've said I've not looked at the rest of the code in particular detail, so I won't rule out the possibility that there are other logical errors or bugs in there somewhere which could cause a segfault!

Hope this is of some help to you.
Cheers for now,
Jas.

commented: Nice comments +27

BTW: I forgot to mention the header files you've included.
You don't need to include the old C header files (stdlib.h, stdio.h and string.h) so they can also be removed!

@dmr215, please provide the code which you say is almost working. This code is far from even compiling let alone execution. Another observation is that this code's written a lot from the POV of java(don't know about PHP as i've never used that.) e.g.
1. unlike java, in C++ all named objects are real objects and not references to them so we never pass any user-defined Object instances as function parameters but pointers/references e.g. Node(const Object& obj, const Node* n) instead of Node(Object obj, Node* n)... just a matter of efficiency.
2. In C++, unlike Java, arrays can't be declared with variable length like int iarray[n], we need to give a constant there. In C++ we resort to int* array = new int[n] and when done with it, delete [] iarray.
3. Another very important difference is usage of pointers, when you allocate memory using new or malloc, you need to free this memory using delete or free accordingly or else this memory is leaked.
Apart from these, most of things are pretty much okay.. and yes, if you submit the almost working code, people may be ready to help you as no one would want to sit and make such huge code compileable and runnable. :icon_cool:

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.