Search code examples
c++listtemplateslinked-list

Linked list in template


I'm working on a project at University while reading a course in C++. We're currently working with linked lists and have started working with templates as well. Somehow I can not get my list linked, in other words my next function won't work. I don't get "Segmentation Fault (core dumped)" as I tend to if the pointing was done incorrect, no complaints in the compiling and none as I run the program and add people to the list, the problem is that it doesn't find the next element as I've added it, it only prints out my first element.

This is my template for the elements:

template <class T>
class element {
private:
    element <T> * next;
    T name;
public:
    element <T> * get_nxt () {
        return next;
    }
    void set_name (string nam) {
        name = nam;
    }
    string get_name () {
        return name;
    }
    void set_nxt (element <T> * n) {
        next = n;
    }
};

So when I wan't to link two pointers I use the :

set_nxt (element * n);

So in the code it looks like (I want to set ptr2 as next to ptr1):

ptr1->set_nxt(ptr2);

As I later want to check how many elements my list is containing, it only says one.

Here is the counting function I use to count through them all:

template < class T >
int lista<T>::count (lista<T> & L) {
    element <T> *curr = LIST;
    int nr = 0;
    while (curr) {
        curr = curr->get_nxt();
        ++nr;
    }
    return nr;
}

Somewhere here the problem lies, because this function returns 1 even if I've added 2 or more.

The list has been declared in this way:

template < class T >
class lista {
private:
    element <T> * LIST;
public:
    lista () {
        LIST = NULL;
    }
    void add(lista<T> & , string, int);
    int count(lista<T> & );
    void print (lista <T> & );
};

I have LIST instead of the popular head. I've been staring at the code for what seems hours and I can not find anything wrong. We've been doing linked lists without templates just before and I assumed the linking process was the same for a template of a linked list.

Adding elements:

void lista<T>::add (lista<T> & L, string name, int cond) {
    element <T> *curr = LIST, *fill;
    fill = new element <T>;
    curr = new element <T>;
    if (cond == 0) {
        int nr;
        nr = L.count(L);
        if (nr == 0) {
            curr->set_name (name);
            LIST = curr;
        }
        else if (nr > 0) {
            int i;
            for (i = 1 ; i < nr ; ++i)
                curr = curr->get_nxt();
            fill->set_name(name);
            curr->set_nxt (fill);
            fill->set_nxt(NULL);
        }

Ignore the if (cond == 0) it is non essential to this.


Solution

  • Your lista<T>::add function have several problems:

    • First you assign curr to point to LIST, and the directly reassign to a new node you allocate.

    • When you add the first node to the list (nr == 0) then you don't set the next pointer to NULL.

    • When you add the second node (nr == 1) curr doesn't point to the first node (because of the first point) so you really doesn't add anything at all.

    • Because of the previous problem, you will not add any nodes at all to the list, since all nodes except the first one will be the second and you fail to actually add it.

    All of these problems would have been very clear to you if you stepped through the code line by line in a debugger.


    If it was me making the add function, it would look something like this:

    void lista<T>::add (lista<T> & L, string name, int cond) {
        if (cond == 0)
            return;
    
        if (LIST == nullptr) {
            // Adding the first node in the list
            LIST = new element<T>;
            LIST->set_nxtT(nullptr);
            LIST->set_name(name);
        } else {
            // First find the last node
            element<T>* last;
            for (last = LIST; last->get_nxt() != nullptr; last = last->get_nxt())
                ;
    
            // Add a new node
            last->set_nxt(new element<T>);
            last->get_nxt()->set_nxt(nullptr);
            last->get_nxt()->set_name(name);
        }
    }