SH7890
SH7890

Reputation: 555

C++ Linked List printing Crash

I'm not new to programming, but learning C++. To do this, I'm implementing the "standard" data structures in the C++ language. I'm starting with Linked Lists. I understand how they work and all that. However, when I try to print out the list, it doesn't stop when it's supposed to. I set the last pointer to nullptr and all that and have researched this problem heavily on the internet, but I cannot find what I'm doing different from everyone else. Here's the code:

template<typename T>
void LinkedList<T>::print_list(){

    list_node<T> *pos = this->start;

    while(pos != nullptr){
       cout << "PRInting" <<pos->data<<endl <<pos->next;

        pos = pos->next;
    }
}

Here's the Full Code:

#ifndef LINKEDLIST_H_INCLUDED
#define LINKEDLIST_H_INCLUDED

#include <iostream>

using std::cout;
using std::endl;
template <class T>
struct list_node{
    T data;
    list_node<T> *next;
};
template <class T>
class LinkedList{
private:
    list_node<T> *start;

public:
    LinkedList();
    LinkedList(T firstData);
    ~LinkedList();
    void insert_item(T item);
    void delete_item(T item);
    list_node<T>* search_list();
    void print_list();
};



//constructors and destructor
template <typename T>
LinkedList<T>::LinkedList(){
    this->start = nullptr;
}
template <typename T>
LinkedList<T>::LinkedList(T firstData){
    list_node<T> newNode = {
        firstData,
        nullptr
    };
    this->start = &newNode;
    cout <<"Constructor" <<this->start->data<<endl;
}
template <typename T>
LinkedList<T>::~LinkedList(){
    this->start = nullptr;
}

//Debugging print function
template<typename T>
void LinkedList<T>::print_list(){
    list_node<T> *pos = this->start;
    while(pos != nullptr){
        cout << "PRInting" <<pos->data<<endl <<pos->next;
        pos = pos->next;
    }
    //cout << pos->data;
}


//Operations on Linked Lists
template <typename T>
void LinkedList<T>::insert_item(T item){
    list_node<T> *insertNode;
    insertNode->data = item;
    insertNode->next = this->start;
    this->start = insertNode;
    cout << "After insert " <<this->start->data << '\n' << this->start->next->data<<endl;
}

#endif // LINKEDLIST_H_INCLUDED

Upvotes: 3

Views: 172

Answers (1)

Algirdas Preidžius
Algirdas Preidžius

Reputation: 1767

You have 2 different problems regarding node insertion, that are present in your code.

  1. In your constructor: You are creating a local variable newNode, and storing its memory address in this->start. However, newNode object will be destroyed upon leaving the scope of the constructor, and trying to dereference it will result in UB (undefined behavior). You should allocate the node dynamically, so it won't get destroyed once it leaves the scope:

    LinkedList<T>::LinkedList(T firstData){
        this->start = new list_node<T>;
        this->start->data = firstData;
        this->start->next = nullptr;
        cout <<"Constructor" <<this->start->data<<endl;
    }
    
  2. In your insert_item procedure: You are dereferencing local pointer insertNode, even though, no actual memory was allocated for it, and dereferencing it results in UB, as well. Correct version would look like:

    template <typename T>
    void LinkedList<T>::insert_item(T item){
        list_node<T> *insertNode = new list_node<T>;
        insertNode->data = item;
        insertNode->next = this->start;
        this->start = insertNode;
        cout << "After insert " <<this->start->data << '\n' << this->start->next->data<<endl;
        }
    
  3. And now, since we are doing dynamic memory allocation, we need to free it in the destructor (C++ has no garbage collection), so simply assigning start to nullptr won't be enough:

    template <typename T>
        LinkedList<T>::~LinkedList(){
            list_node<T> *pos = this->start;
            while (pos != nullptr){
                list_node<T>* nextPos = pos->next;
                delete pos;
                pos = nextPos;
            }
        }
    

Upvotes: 4

Related Questions