Muhammad Iqbal
Muhammad Iqbal

Reputation: 77

Linkedlist template with class object not working

I have created this Dictionary class and a Linkedlist template which takes this class as the type. In the main() function I am trying to make an object of Dictionary class and passing the Dictionary as the type for Linkedlist template. Later when I pass the created Dictionary class object to LinkedList's insertHead() or initHead() function and try to print the data through accessing the head's data and calling Dictionary member function print(), It does not prints the data (32, A). insertHead() prints a "0-" and initHead() gives segmentation fault. Is there a way I can fix the issue?

class Dictionary {
public:
    int index;
    string data;
public:
    Dictionary(int index = 0, string data = ""){
        this->index = index;
        this->data = data;
    }

    Dictionary(string data){
        this->data = data;
    }

    void setIndex(int index){
        this->index = index;
    }

    void setData(string data){
        this->data = data;
    }

    Dictionary operator=(Dictionary const & obj){
        Dictionary dict;
        dict.index = obj.index;
        dict.data = obj.data;
        return dict;
    }

    void print(){
        cout << index << "-" << data << endl;
    }

    friend bool operator== (const Dictionary &d1, const Dictionary &d2);
    friend bool operator!= (const Dictionary &d1, const Dictionary &d2);
};

bool operator== (const Dictionary &d1, const Dictionary &d2){
    return (d1.data == d2.data);
}

bool operator!= (const Dictionary &d1, const Dictionary &d2){
    return !(d1 == d2);
}


int main(){
    Dictionary d(32, "A");
    LinkedList<Dictionary> l;
    l.insertHead(d);
    l.head->data.print();
}

Here is the code for LinkedList template class:

#include <iostream>
using namespace std;

template <typename T>
class Node {
public:
    T data;
    Node *next;
    Node *prev;

    Node(){};
};

template <typename T>
class LinkedList {
public:
    Node<T> *head;
    Node<T> *tail;

public:
    LinkedList(){
        head = NULL;
        tail = NULL;
    }

    void initHead(T item){
        head->next = NULL;
        head->prev = NULL;
        head->data = item;
    }

    void insertHead(T item){
        Node<T> *tmp = new Node<T>();
        if (head == nullptr){
            head = tmp;
            head->prev = nullptr;
            head->data = item;
            head->next = nullptr;
            tail = tmp;
        } else {
            tmp->next = head;
            tmp->data = item;
            tmp->prev = nullptr;
            head->prev = tmp;
            head = tmp;
        }
    }

    void insertLast(T item){
        Node<T> *tmp = new Node<T>();
        tmp->data = item;
        if (head == nullptr){
            head = tmp;
            head->prev = nullptr;
            head->next = nullptr;
            tail = tmp;
        } else {
            tmp->prev = tail;
            tail->next = tmp;
            tmp->next = nullptr;
            tail = tmp;
        }
    }

    void insertNext(T item){
        Node<T> *tmp = new Node<T>();
        tmp->next = nullptr;
        tmp->data = item;
        tmp->prev = nullptr;

        Node<T> *iter = head;
        while (iter != nullptr){
            if (iter->next == nullptr){
                iter->next = tmp;
                tmp->prev = iter;
                return;
            }
            iter = iter->next;
        }
    }

    // Returns 0 if Not found. Always add a check
    // for 0 before accessing the tmp->data

    Node<T>* find(T item){
        Node<T> *tmp = head;
        while(tmp && tmp->data != item){
            tmp = tmp->next;
        }
        return tmp;
    }

    bool deleteNode(Node<T>* node){
        if (node == nullptr){
            return false;
        } else if (node == head){
            head = node->next;
            delete node;
            return true;
        } else {
            Node<T> *tmp = head;
            while (tmp){
                if (tmp->next == node){
                    tmp->next = node->next;
                    delete node;
                    return true;
                }
                tmp = tmp->next;
            }
        }
        return false;
    }

    void print(){
        Node<T> *tmp;
        tmp = head;
        while (tmp != nullptr){
            cout << tmp->data << "->";
            tmp = tmp->next;
        }
        cout << endl;
    }
};

Upvotes: 0

Views: 65

Answers (1)

artunc
artunc

Reputation: 190

In the function insertHead I changed the head->data = item to next lines

head->data.index = item.index; head->data.data = item.data;

then it printed 32-A. So you have a problem with = operator overloading. Then I changed your overloading as follows:

void operator=(const Dictionary & obj){ index = obj.index; data = obj.data; }

The = operation on your Dictionary works fine now.

If you want to use original signature as you state in comments you should update previous overloading function as:

 Dictionary& operator=(Dictionary const & obj){
    this->index = obj.index;
    this->data = obj.data;
    return *this;
}

I want to improve the answer with a self assignment check. While overloading = operator, internals goes like this:

  1. Deallocate the memory hold by this
  2. Allocate the memory for given parameter object
  3. Copy values and return

Therefore, if you try something like:

Dictionary dummyDict;
dummyDict=dummyDict;

your program will blow. So the final answer will be:

Dictionary& operator=(Dictionary const & obj){
    if(this == &obj){
        return *this;
    }
    this->index = obj.index;
    this->data = obj.data;
    return *this;
}

Upvotes: 2

Related Questions