Home > OS >  Doubly linked list not taking input after calling a delete function
Doubly linked list not taking input after calling a delete function

Time:09-28

Greetings stack overflow. My program is supposed to take a user inputted line of characters and append them to a list. The program is also supposed to delete the most recent character appended if a hashtag is read in the input.

My program mostly works, but I run into errors when I try to break it by adding too many hashtags. Upon doing this the list stops accepting appends will display nothing if one too many hashtags are used.

I hope I only included what I thought was useful code, sorry if the main function was not necessary.

#include <iostream>
using namespace std;


class doubleList
{
    public:
        doubleList() { first = NULL; } // constructor

        void append(char); // adds entry to the end of the list
        void remove_last(); // removes the last item from a list

        friend ostream& operator<<(ostream& out, const doubleList& l); // outputs in forward order

    private:
        struct Node
        {
            char data;
            Node *next;
            Node *prev;
        };
        Node *first;
        Node *last;  
};

void doubleList::append(char entry)
{
    Node* temp = new Node();
    temp -> data = entry;
    temp -> next = NULL;

    if (first == NULL)
    {
        first = temp;
        last = temp;
    }
    else
    {
        last -> next = temp;
        temp -> prev = last;
        last = temp;
    }
}

void doubleList::remove_last()
{
    if (first -> next == NULL)
    {
        delete first;
    }
    else if (first != NULL)
    {
        last = last -> prev;
        delete last -> next;
        last -> next = NULL;
    }
}

ostream& operator<<(ostream& out, const doubleList& l)
{
    doubleList::Node* q;
    q = l.first;

    while (q != NULL)
    {
        out << q -> data;
        q = q -> next;
    }
    return out;
}

int main()
{
    doubleList list;
    char ch[100];

    cout << "Enter a line of characters; # will delete the most recent character." << endl;
        for (int i = 0; i < 100; i  )
        {
            cin.get(ch[i]);
            list.append(ch[i]);

            if (ch[i] == '#')
            {
                list.remove_last();
                list.remove_last(); // called twice becaue it removes the hashtag from the list
            }                       // and i was too lazy to make it so it doesnt do that so this
                                    // is simply an easier fix
            if (ch[i] == '\n')      // exits the loop when enter is clicked
                break;
        }

    cout << list;

    return 0;
}

A successful run of my program would look like:

Enter a line of characters; # will delete the most recent character.

abcd##fg

abfg

My program when too many hashtags are added:

Enter a line of characters; # will delete the most recent character.

ab#####efgh

Nothing is shown after user input is taken. Thanks in advance.

CodePudding user response:

You should also set the pointer last to nullptr in the constructor

doubleList() { first = nullptr; last = nullptr; }

The function append is incorrect because it does not set the data member prev of the first node appended to the list. It should be written like

void doubleList::append(char entry)
{
    Node* temp = new Node();
    temp -> data = entry;
    temp -> next = nullptr;
    temp -> prev = last; 

    if (first == NULL)
    {
        first = temp;
    }
    else
    {
        last -> next = temp;
    }

    last = temp;
}

The function removeList can invoke undefined behavior because in the very beginning of the function it does not check whether the pointer first is equal to nullptr. And after deleting the node pointed to by the pointer first it does not set the pointers first and last to nullptr. The function can be defined the following way.

void doubleList::remove_last()
{
    if ( last )
    {
        Node *tmp = last;

        last = last->prev;

        if ( last != nullptr )
        {
            last->next = nullptr;
        }
        else
        {
            first = nullptr;
        }

        delete temp;
    }
}

CodePudding user response:

You rely on first being NULL when deallocated in remove_last() but do not set it after the free. As your code is incomplete, I cannot tell what last is, and why you your logic doesn't rely on it in remove_last() instead of first.

Something along these lines (untested);

void doubleList::remove_last() {
    if(!last) return;

    if(last == first) {
       free last;
       first = nullptr;
       last = nullptr;
       return;
    }
  
    last = last->prev;
    free last->next;
    last->next = nullptr;
}
  • Related